15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/app_window/app_window_geometry_cache.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_path.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/mock_pref_change_callback.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/prefs/pref_service_factory.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/prefs/testing_pref_store.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/pref_registry/pref_registry_syncable.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/test/test_browser_context.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_utils.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/extension_pref_value_map.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/extensions_test.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/null_app_sorting.h" 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/common/extension_builder.h" 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/common/value_builder.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using content::BrowserThread; 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace extensions { 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace { 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kWindowId[] = "windowid"; 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kWindowId2[] = "windowid2"; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Create a very simple extension with id. 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_refptr<Extension> CreateExtension(const std::string& id) { 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return ExtensionBuilder() 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .SetManifest(DictionaryBuilder().Set("name", "test").Set( 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "version", "0.1")) 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .SetID(id) 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .Build(); 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base class for tests. 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass AppWindowGeometryCacheTest : public ExtensionsTest { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppWindowGeometryCacheTest() 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : ui_thread_(BrowserThread::UI, &ui_message_loop_) {} 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // testing::Test overrides: 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void SetUp() OVERRIDE; 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void TearDown() OVERRIDE; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void AddGeometryAndLoadExtension(const std::string& extension_id, 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& window_id, 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Rect& bounds, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Rect& screen_bounds, 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::WindowShowState state); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Spins the UI threads' message loops to make sure any task 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // posted to sync the geometry to the value store gets a chance to run. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForSync(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void LoadExtension(const std::string& extension_id); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UnloadExtension(const std::string& extension_id); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Creates and adds an extension with associated prefs. Returns the extension 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // ID. 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string AddExtensionWithPrefs(const std::string& name); 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::MessageLoopForUI ui_message_loop_; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread ui_thread_; 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ExtensionPrefValueMap> extension_pref_value_map_; 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<PrefService> pref_service_; 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ExtensionPrefs> extension_prefs_; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<AppWindowGeometryCache> cache_; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppWindowGeometryCacheTest::SetUp() { 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ExtensionsTest::SetUp(); 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Set up all the dependencies of ExtensionPrefs. 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_pref_value_map_.reset(new ExtensionPrefValueMap); 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::PrefServiceFactory factory; 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci factory.set_user_prefs(new TestingPrefStore); 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci factory.set_extension_prefs(new TestingPrefStore); 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci user_prefs::PrefRegistrySyncable* pref_registry = 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new user_prefs::PrefRegistrySyncable; 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Prefs should be registered before the PrefService is created. 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ExtensionPrefs::RegisterProfilePrefs(pref_registry); 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pref_service_ = factory.Create(pref_registry).Pass(); 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_prefs_.reset(ExtensionPrefs::Create( 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pref_service_.get(), 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context()->GetPath().AppendASCII("Extensions"), 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_pref_value_map_.get(), 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<AppSorting>(new NullAppSorting), 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci false /* extensions_disabled */, 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<ExtensionPrefsObserver*>())); 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cache_.reset( 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new AppWindowGeometryCache(browser_context(), extension_prefs_.get())); 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cache_->SetSyncDelayForTests(0); 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppWindowGeometryCacheTest::TearDown() { 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cache_.reset(); 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_prefs_.reset(); 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pref_service_.reset(); 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_pref_value_map_.reset(); 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ExtensionsTest::TearDown(); 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppWindowGeometryCacheTest::AddGeometryAndLoadExtension( 117b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const std::string& extension_id, 118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const std::string& window_id, 119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const gfx::Rect& bounds, 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const gfx::Rect& screen_bounds, 121b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ui::WindowShowState state) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue* value = new base::DictionaryValue; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetInteger("x", bounds.x()); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetInteger("y", bounds.y()); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetInteger("w", bounds.width()); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetInteger("h", bounds.height()); 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch value->SetInteger("screen_bounds_x", screen_bounds.x()); 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch value->SetInteger("screen_bounds_y", screen_bounds.y()); 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch value->SetInteger("screen_bounds_w", screen_bounds.width()); 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch value->SetInteger("screen_bounds_h", screen_bounds.height()); 132b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) value->SetInteger("state", state); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetWithoutPathExpansion(window_id, value); 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_prefs_->SetGeometryCache(extension_id, dict.Pass()); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadExtension(extension_id); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppWindowGeometryCacheTest::WaitForSync() { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunAllPendingInMessageLoop(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppWindowGeometryCacheTest::LoadExtension( 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cache_->LoadGeometryFromStorage(extension_id); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForSync(); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppWindowGeometryCacheTest::UnloadExtension( 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<Extension> extension = CreateExtension(extension_id); 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cache_->OnExtensionUnloaded(browser_context(), 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension.get(), 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UnloadedExtensionInfo::REASON_DISABLE); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForSync(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string AppWindowGeometryCacheTest::AddExtensionWithPrefs( 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& name) { 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Generate the extension with a path based on the name so that extensions 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // with different names will have different IDs. 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::FilePath path = 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context()->GetPath().AppendASCII("Extensions").AppendASCII(name); 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<Extension> extension = 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ExtensionBuilder() 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci .SetManifest( 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DictionaryBuilder().Set("name", "test").Set("version", "0.1")) 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci .SetPath(path) 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci .Build(); 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_prefs_->OnExtensionInstalled( 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension.get(), 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Extension::ENABLED, 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci syncer::StringOrdinal::CreateInitialOrdinal(), 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string()); 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return extension->id(); 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test getting geometry from an empty store. 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(AppWindowGeometryCacheTest, GetGeometryEmptyStore) { 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string extension_id = AddExtensionWithPrefs("ext1"); 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_FALSE(cache_->GetGeometry(extension_id, kWindowId, NULL, NULL, NULL)); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test getting geometry for an unknown extension. 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(AppWindowGeometryCacheTest, GetGeometryUnkownExtension) { 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string extension_id1 = AddExtensionWithPrefs("ext1"); 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string extension_id2 = AddExtensionWithPrefs("ext2"); 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddGeometryAndLoadExtension(extension_id1, 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kWindowId, 190b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) gfx::Rect(4, 5, 31, 43), 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect(0, 0, 1600, 900), 1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ui::SHOW_STATE_NORMAL); 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_FALSE(cache_->GetGeometry(extension_id2, kWindowId, NULL, NULL, NULL)); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test getting geometry for an unknown window in a known extension. 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(AppWindowGeometryCacheTest, GetGeometryUnkownWindow) { 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string extension_id = AddExtensionWithPrefs("ext1"); 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddGeometryAndLoadExtension(extension_id, 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kWindowId, 201b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) gfx::Rect(4, 5, 31, 43), 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect(0, 0, 1600, 900), 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ui::SHOW_STATE_NORMAL); 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_FALSE(cache_->GetGeometry(extension_id, kWindowId2, NULL, NULL, NULL)); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test that loading geometry, screen_bounds and state from the store works 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// correctly. 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(AppWindowGeometryCacheTest, GetGeometryAndStateFromStore) { 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string extension_id = AddExtensionWithPrefs("ext1"); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds(4, 5, 31, 43); 212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect screen_bounds(0, 0, 1600, 900); 213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ui::WindowShowState state = ui::SHOW_STATE_NORMAL; 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddGeometryAndLoadExtension( 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id, kWindowId, bounds, screen_bounds, state); 216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) gfx::Rect new_bounds; 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect new_screen_bounds; 218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ui::WindowShowState new_state = ui::SHOW_STATE_DEFAULT; 219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ASSERT_TRUE(cache_->GetGeometry( 220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extension_id, kWindowId, &new_bounds, &new_screen_bounds, &new_state)); 221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ASSERT_EQ(bounds, new_bounds); 222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(screen_bounds, new_screen_bounds); 223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ASSERT_EQ(state, new_state); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 226a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Test corrupt bounds will not be loaded. 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(AppWindowGeometryCacheTest, CorruptBounds) { 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string extension_id = AddExtensionWithPrefs("ext1"); 229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect bounds; 230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect screen_bounds(0, 0, 1600, 900); 231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ui::WindowShowState state = ui::SHOW_STATE_NORMAL; 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddGeometryAndLoadExtension( 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id, kWindowId, bounds, screen_bounds, state); 234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect new_bounds; 235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect new_screen_bounds; 236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ui::WindowShowState new_state = ui::SHOW_STATE_DEFAULT; 237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_FALSE(cache_->GetGeometry( 238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension_id, kWindowId, &new_bounds, &new_screen_bounds, &new_state)); 239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(new_bounds.IsEmpty()); 240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(new_screen_bounds.IsEmpty()); 241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(new_state, ui::SHOW_STATE_DEFAULT); 242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Test corrupt screen bounds will not be loaded. 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(AppWindowGeometryCacheTest, CorruptScreenBounds) { 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string extension_id = AddExtensionWithPrefs("ext1"); 247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect bounds(4, 5, 31, 43); 248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect screen_bounds; 249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ui::WindowShowState state = ui::SHOW_STATE_NORMAL; 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddGeometryAndLoadExtension( 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id, kWindowId, bounds, screen_bounds, state); 252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect new_bounds; 253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect new_screen_bounds; 254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ui::WindowShowState new_state = ui::SHOW_STATE_DEFAULT; 255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_FALSE(cache_->GetGeometry( 256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension_id, kWindowId, &new_bounds, &new_screen_bounds, &new_state)); 257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(new_bounds.IsEmpty()); 258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(new_screen_bounds.IsEmpty()); 259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(new_state, ui::SHOW_STATE_DEFAULT); 260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Test corrupt state will not be loaded. 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(AppWindowGeometryCacheTest, CorruptState) { 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string extension_id = AddExtensionWithPrefs("ext1"); 265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect bounds(4, 5, 31, 43); 266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect screen_bounds(0, 0, 1600, 900); 267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ui::WindowShowState state = ui::SHOW_STATE_DEFAULT; 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddGeometryAndLoadExtension( 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id, kWindowId, bounds, screen_bounds, state); 270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect new_bounds; 271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect new_screen_bounds; 272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ui::WindowShowState new_state = ui::SHOW_STATE_DEFAULT; 273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_FALSE(cache_->GetGeometry( 274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension_id, kWindowId, &new_bounds, &new_screen_bounds, &new_state)); 275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(new_bounds.IsEmpty()); 276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(new_screen_bounds.IsEmpty()); 277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(new_state, ui::SHOW_STATE_DEFAULT); 278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test saving geometry, screen_bounds and state to the cache and state store, 281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// and reading it back. 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(AppWindowGeometryCacheTest, SaveGeometryAndStateToStore) { 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string extension_id = AddExtensionWithPrefs("ext1"); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string window_id(kWindowId); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inform cache of extension 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadExtension(extension_id); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // update geometry stored in cache 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds(4, 5, 31, 43); 291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect screen_bounds(0, 0, 1600, 900); 292b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ui::WindowShowState state = ui::SHOW_STATE_NORMAL; 293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cache_->SaveGeometry(extension_id, window_id, bounds, screen_bounds, state); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // make sure that immediately reading back geometry works 296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) gfx::Rect new_bounds; 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect new_screen_bounds; 298b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ui::WindowShowState new_state = ui::SHOW_STATE_DEFAULT; 299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ASSERT_TRUE(cache_->GetGeometry( 300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extension_id, window_id, &new_bounds, &new_screen_bounds, &new_state)); 301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ASSERT_EQ(bounds, new_bounds); 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(screen_bounds, new_screen_bounds); 303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ASSERT_EQ(state, new_state); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unload extension to force cache to save data to the state store 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnloadExtension(extension_id); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // check if geometry got stored correctly in the state store 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue* dict = 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_prefs_->GetGeometryCache(extension_id); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(dict); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(dict->HasKey(window_id)); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int v; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(dict->GetInteger(window_id + ".x", &v)); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bounds.x(), v); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(dict->GetInteger(window_id + ".y", &v)); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bounds.y(), v); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(dict->GetInteger(window_id + ".w", &v)); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bounds.width(), v); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(dict->GetInteger(window_id + ".h", &v)); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bounds.height(), v); 323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(dict->GetInteger(window_id + ".screen_bounds_x", &v)); 324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(screen_bounds.x(), v); 325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(dict->GetInteger(window_id + ".screen_bounds_y", &v)); 326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(screen_bounds.y(), v); 327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(dict->GetInteger(window_id + ".screen_bounds_w", &v)); 328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(screen_bounds.width(), v); 329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(dict->GetInteger(window_id + ".screen_bounds_h", &v)); 330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(screen_bounds.height(), v); 331b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ASSERT_TRUE(dict->GetInteger(window_id + ".state", &v)); 332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ASSERT_EQ(state, v); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reload extension 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadExtension(extension_id); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and make sure the geometry got reloaded properly too 337b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ASSERT_TRUE(cache_->GetGeometry( 338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extension_id, window_id, &new_bounds, &new_screen_bounds, &new_state)); 339b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ASSERT_EQ(bounds, new_bounds); 340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(screen_bounds, new_screen_bounds); 341b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ASSERT_EQ(state, new_state); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we won't do writes to the state store for SaveGeometry calls 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which don't change the state we already have. 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(AppWindowGeometryCacheTest, NoDuplicateWrites) { 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) using testing::_; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) using testing::Mock; 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string extension_id = AddExtensionWithPrefs("ext1"); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds1(100, 200, 300, 400); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds2(200, 400, 600, 800); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds2_duplicate(200, 400, 600, 800); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect screen_bounds1(0, 0, 1600, 900); 356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect screen_bounds2(0, 0, 1366, 768); 357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect screen_bounds2_duplicate(0, 0, 1366, 768); 358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MockPrefChangeCallback observer(pref_service_.get()); 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrefChangeRegistrar registrar; 3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci registrar.Init(pref_service_.get()); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar.Add("extensions.settings", observer.GetCallback()); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the first bounds - it should do > 0 writes. 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(observer, OnPreferenceChanged(_)); 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cache_->SaveGeometry( 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id, kWindowId, bounds1, screen_bounds1, ui::SHOW_STATE_NORMAL); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForSync(); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mock::VerifyAndClearExpectations(&observer); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write a different bounds - it should also do > 0 writes. 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(observer, OnPreferenceChanged(_)); 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cache_->SaveGeometry( 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id, kWindowId, bounds2, screen_bounds1, ui::SHOW_STATE_NORMAL); 375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch WaitForSync(); 376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Mock::VerifyAndClearExpectations(&observer); 377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Write a different screen bounds - it should also do > 0 writes. 379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_CALL(observer, OnPreferenceChanged(_)); 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cache_->SaveGeometry( 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id, kWindowId, bounds2, screen_bounds2, ui::SHOW_STATE_NORMAL); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForSync(); 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mock::VerifyAndClearExpectations(&observer); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Write a different state - it should also do > 0 writes. 386b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EXPECT_CALL(observer, OnPreferenceChanged(_)); 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cache_->SaveGeometry(extension_id, 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kWindowId, 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bounds2, 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) screen_bounds2, 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::SHOW_STATE_MAXIMIZED); 392b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) WaitForSync(); 393b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Mock::VerifyAndClearExpectations(&observer); 394b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Write a bounds, screen bounds and state that's a duplicate of what we 396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // already have. This should not do any writes. 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(observer, OnPreferenceChanged(_)).Times(0); 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cache_->SaveGeometry(extension_id, 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kWindowId, 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bounds2_duplicate, 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) screen_bounds2_duplicate, 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::SHOW_STATE_MAXIMIZED); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForSync(); 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mock::VerifyAndClearExpectations(&observer); 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that no more than kMaxCachedWindows windows will be cached. 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(AppWindowGeometryCacheTest, MaxWindows) { 4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string extension_id = AddExtensionWithPrefs("ext1"); 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // inform cache of extension 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoadExtension(extension_id); 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect bounds(4, 5, 31, 43); 414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect screen_bounds(0, 0, 1600, 900); 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < AppWindowGeometryCache::kMaxCachedWindows + 1; ++i) { 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string window_id = "window_" + base::IntToString(i); 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cache_->SaveGeometry( 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id, window_id, bounds, screen_bounds, ui::SHOW_STATE_NORMAL); 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The first added window should no longer have cached geometry. 422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_FALSE(cache_->GetGeometry(extension_id, "window_0", NULL, NULL, NULL)); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // All other windows should still exist. 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 1; i < AppWindowGeometryCache::kMaxCachedWindows + 1; ++i) { 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string window_id = "window_" + base::IntToString(i); 426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_TRUE(cache_->GetGeometry(extension_id, window_id, NULL, NULL, NULL)); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace extensions 431