Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: chrome/browser/extensions/shell_window_geometry_cache.cc

Issue 10871086: First part of remembering platform app window geometry. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 #include "chrome/browser/extensions/shell_window_geometry_cache.h"
6
7 #include "base/bind.h"
8 #include "chrome/browser/extensions/state_store.h"
9 #include "chrome/common/chrome_notification_types.h"
10 #include "chrome/common/extensions/extension.h"
11 #include "content/public/browser/notification_service.h"
12 #include "content/public/browser/notification_types.h"
13
14 namespace {
15
16 // Keys for serialization to and from Value to store in the preferences.
17 const char kWindowGeometryKey[] = "window_geometry";
18
19 // The timeout in milliseconds before we'll persist window geometry to the
20 // StateStore.
21 const int kSyncTimeoutMilliseconds = 1000;
22
23 } // namespace
24
25 namespace extensions {
26
27 ShellWindowGeometryCache::ShellWindowGeometryCache(Profile* profile,
28 StateStore* state_store)
29 : store_(state_store) {
30 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
31 content::Source<Profile>(profile));
32 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
33 content::Source<Profile>(profile));
34
35 store_->RegisterKey(kWindowGeometryKey);
36 }
37
38 ShellWindowGeometryCache::~ShellWindowGeometryCache() {
39 SyncToStorage();
40 }
41
42 void ShellWindowGeometryCache::SaveWindowGeometry(
43 const std::string& extension_id,
44 const std::string& window_id,
45 const gfx::Rect& bounds) {
46 std::map<std::string, gfx::Rect>& geometry = cache_[extension_id];
47 geometry[window_id] = bounds;
48
49 unsynced_extensions_.insert(extension_id);
50
51 // We don't use Reset() because the timer may not yet be running.
52 // (In that case Stop() is a no-op.)
53 sync_timer_.Stop();
54 sync_timer_.Start(FROM_HERE,
55 base::TimeDelta::FromMilliseconds(kSyncTimeoutMilliseconds), this,
56 &ShellWindowGeometryCache::SyncToStorage);
57 }
58
59 void ShellWindowGeometryCache::SyncToStorage() {
60 std::set<std::string> tosync;
61 tosync.swap(unsynced_extensions_);
62 for (std::set<std::string>::const_iterator it = tosync.begin(),
63 eit = tosync.end(); it != eit; ++it) {
64 const std::string& extension_id = *it;
65 const std::map<std::string, gfx::Rect>& geometry = cache_[extension_id];
66
67 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
68 for (std::map<std::string, gfx::Rect>::const_iterator it =
69 geometry.begin(), eit = geometry.end(); it != eit; ++it) {
70 base::DictionaryValue* value = new base::DictionaryValue;
71 const gfx::Rect& bounds = it->second;
72 value->SetInteger("x", bounds.x());
73 value->SetInteger("y", bounds.y());
74 value->SetInteger("w", bounds.width());
75 value->SetInteger("h", bounds.height());
76 dict->SetWithoutPathExpansion(it->first, value);
77 }
78 store_->SetExtensionValue(extension_id, kWindowGeometryKey,
79 scoped_ptr<base::Value>(dict.release()));
80 }
81 }
82
83 bool ShellWindowGeometryCache::GetWindowGeometry(
84 const std::string& extension_id,
85 const std::string& window_id,
86 gfx::Rect* bounds) const {
87
88 std::map<std::string, std::map<std::string, gfx::Rect> >::const_iterator
89 ext = cache_.find(extension_id);
90
91 // Not in the map means loading data for the extension didn't finish yet
asargent_no_longer_on_chrome 2012/08/28 18:49:41 nit: end sentence with a period. Also, it could
Marijn Kruisselbrink 2012/08/28 22:14:58 Currently GeometryFromStorage creates an entry in
92 if (ext == cache_.end())
93 return false;
94
95 std::map<std::string, gfx::Rect>::const_iterator win = ext->second.find(
96 window_id);
97
98 if (win == ext->second.end())
99 return false;
100
101 *bounds = win->second;
102 return true;
103 }
104
105 void ShellWindowGeometryCache::Observe(
106 int type, const content::NotificationSource& source,
107 const content::NotificationDetails& details) {
108 switch (type) {
109 case chrome::NOTIFICATION_EXTENSION_LOADED: {
110 std::string extension_id =
111 content::Details<const Extension>(details).ptr()->id();
112 OnExtensionLoaded(extension_id);
113 break;
114 }
115 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
116 std::string extension_id =
117 content::Details<const UnloadedExtensionInfo>(details).
118 ptr()->extension->id();
119 OnExtensionUnloaded(extension_id);
120 break;
121 }
122 default:
123 NOTREACHED();
124 return;
125 }
126 }
127
128 void ShellWindowGeometryCache::OnExtensionLoaded(
129 const std::string& extension_id)
130 {
131 store_->GetExtensionValue(extension_id, kWindowGeometryKey,
132 base::Bind(&ShellWindowGeometryCache::GeometryFromStorage,
133 AsWeakPtr(), extension_id));
134
135 }
136
137 void ShellWindowGeometryCache::OnExtensionUnloaded(
138 const std::string& extension_id)
139 {
140 SyncToStorage();
141 cache_.erase(extension_id);
142 }
143
144 void ShellWindowGeometryCache::GeometryFromStorage(
145 const std::string& extension_id, scoped_ptr<base::Value> value) {
146 // TODO(mek): what should happen if an extension is already unloaded by the
147 // time this code is executed
148 std::map<std::string, gfx::Rect>& geometry = cache_[extension_id];
asargent_no_longer_on_chrome 2012/08/28 18:49:41 It might be good to see if cache_ already contains
Marijn Kruisselbrink 2012/08/28 22:14:58 Done.
149
150 base::DictionaryValue* dict;
151 if (value.get() && value->GetAsDictionary(&dict)) {
152 for (base::DictionaryValue::Iterator it(*dict); it.HasNext();
153 it.Advance()) {
154 const base::DictionaryValue* geom;
155 if (it.value().GetAsDictionary(&geom)) {
156 gfx::Rect& bounds = geometry[it.key()];
157
158 int i;
159 if (geom->GetInteger("x", &i)) bounds.set_x(i);
160 if (geom->GetInteger("y", &i)) bounds.set_y(i);
161 if (geom->GetInteger("w", &i)) bounds.set_width(i);
162 if (geom->GetInteger("h", &i)) bounds.set_height(i);
163 }
164 }
165 }
166 }
167
168
169 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698