1 // Copyright (c) 2012 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 CHROME_BROWSER_EXTENSIONS_SHELL_WINDOW_GEOMETRY_CACHE_H_ 6 #define CHROME_BROWSER_EXTENSIONS_SHELL_WINDOW_GEOMETRY_CACHE_H_ 7 8 #include <map> 9 #include <set> 10 #include <string> 11 12 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/singleton.h" 14 #include "base/time/time.h" 15 #include "base/timer/timer.h" 16 #include "base/values.h" 17 #include "components/browser_context_keyed_service/browser_context_keyed_service.h" 18 #include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h" 19 #include "content/public/browser/notification_observer.h" 20 #include "content/public/browser/notification_registrar.h" 21 #include "ui/base/ui_base_types.h" 22 #include "ui/gfx/rect.h" 23 24 class Profile; 25 26 namespace extensions { 27 class ExtensionPrefs; 28 } 29 30 namespace apps { 31 32 // A cache for persisted geometry of shell windows, both to not have to wait 33 // for IO when creating a new window, and to not cause IO on every window 34 // geometry change. 35 class ShellWindowGeometryCache 36 : public BrowserContextKeyedService, 37 public content::NotificationObserver { 38 public: 39 class Factory : public BrowserContextKeyedServiceFactory { 40 public: 41 static ShellWindowGeometryCache* GetForContext( 42 content::BrowserContext* context, 43 bool create); 44 45 static Factory* GetInstance(); 46 private: 47 friend struct DefaultSingletonTraits<Factory>; 48 49 Factory(); 50 virtual ~Factory(); 51 52 // BrowserContextKeyedServiceFactory 53 virtual BrowserContextKeyedService* BuildServiceInstanceFor( 54 content::BrowserContext* context) const OVERRIDE; 55 virtual bool ServiceIsNULLWhileTesting() const OVERRIDE; 56 virtual content::BrowserContext* GetBrowserContextToUse( 57 content::BrowserContext* context) const OVERRIDE; 58 }; 59 60 ShellWindowGeometryCache(Profile* profile, 61 extensions::ExtensionPrefs* prefs); 62 63 virtual ~ShellWindowGeometryCache(); 64 65 // Returns the instance for the given browsing context. 66 static ShellWindowGeometryCache* Get(content::BrowserContext* context); 67 68 // Save the geometry and state associated with |extension_id| and |window_id|. 69 void SaveGeometry(const std::string& extension_id, 70 const std::string& window_id, 71 const gfx::Rect& bounds, 72 const gfx::Rect& screen_bounds, 73 ui::WindowShowState state); 74 75 // Get any saved geometry and state associated with |extension_id| and 76 // |window_id|. If saved data exists, sets |bounds|, |screen_bounds| and 77 // |state| if not NULL and returns true. 78 bool GetGeometry(const std::string& extension_id, 79 const std::string& window_id, 80 gfx::Rect* bounds, 81 gfx::Rect* screen_bounds, 82 ui::WindowShowState* state); 83 84 // BrowserContextKeyedService 85 virtual void Shutdown() OVERRIDE; 86 87 // Maximum number of windows we'll cache the geometry for per app. 88 static const size_t kMaxCachedWindows = 100; 89 90 protected: 91 friend class ShellWindowGeometryCacheTest; 92 93 // For tests, this modifies the timeout delay for saving changes from calls 94 // to SaveGeometry. (Note that even if this is set to 0, you still need to 95 // run the message loop to see the results of any SyncToStorage call). 96 void SetSyncDelayForTests(int timeout_ms); 97 98 private: 99 // Data stored for each window. 100 struct WindowData { 101 WindowData(); 102 ~WindowData(); 103 gfx::Rect bounds; 104 gfx::Rect screen_bounds; 105 ui::WindowShowState window_state; 106 base::Time last_change; 107 }; 108 109 // Data stored for each extension. 110 typedef std::map<std::string, WindowData> ExtensionData; 111 112 // content::NotificationObserver 113 virtual void Observe(int type, 114 const content::NotificationSource& source, 115 const content::NotificationDetails& details) OVERRIDE; 116 117 void LoadGeometryFromStorage(const std::string& extension_id); 118 void OnExtensionUnloaded(const std::string& extension_id); 119 void SyncToStorage(); 120 121 // Preferences storage. 122 extensions::ExtensionPrefs* prefs_; 123 124 // Cached data 125 std::map<std::string, ExtensionData> cache_; 126 127 // Data that still needs saving 128 std::set<std::string> unsynced_extensions_; 129 130 // The timer used to save the data 131 base::OneShotTimer<ShellWindowGeometryCache> sync_timer_; 132 133 // The timeout value we'll use for |sync_timer_|. 134 base::TimeDelta sync_delay_; 135 136 content::NotificationRegistrar registrar_; 137 }; 138 139 } // namespace apps 140 141 #endif // CHROME_BROWSER_EXTENSIONS_SHELL_WINDOW_GEOMETRY_CACHE_H_ 142