| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/shell_window_geometry_cache.h" | 5 #include "chrome/browser/extensions/shell_window_geometry_cache.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "chrome/browser/extensions/extension_prefs.h" | 10 #include "chrome/browser/extensions/extension_prefs.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 content::Source<Profile>(profile)); | 33 content::Source<Profile>(profile)); |
| 34 } | 34 } |
| 35 | 35 |
| 36 ShellWindowGeometryCache::~ShellWindowGeometryCache() { | 36 ShellWindowGeometryCache::~ShellWindowGeometryCache() { |
| 37 SyncToStorage(); | 37 SyncToStorage(); |
| 38 } | 38 } |
| 39 | 39 |
| 40 void ShellWindowGeometryCache::SaveGeometry( | 40 void ShellWindowGeometryCache::SaveGeometry( |
| 41 const std::string& extension_id, | 41 const std::string& extension_id, |
| 42 const std::string& window_id, | 42 const std::string& window_id, |
| 43 const gfx::Rect& bounds) { | 43 const gfx::Rect& bounds, |
| 44 ui::WindowShowState window_state) { |
| 44 ExtensionData& extension_data = cache_[extension_id]; | 45 ExtensionData& extension_data = cache_[extension_id]; |
| 45 | 46 |
| 46 // If we don't have any unsynced changes and this is a duplicate of what's | 47 // If we don't have any unsynced changes and this is a duplicate of what's |
| 47 // already in the cache, just ignore it. | 48 // already in the cache, just ignore it. |
| 48 if (extension_data[window_id].bounds == bounds && | 49 if (extension_data[window_id].bounds == bounds && |
| 50 extension_data[window_id].window_state == window_state && |
| 49 !ContainsKey(unsynced_extensions_, extension_id)) | 51 !ContainsKey(unsynced_extensions_, extension_id)) |
| 50 return; | 52 return; |
| 51 | 53 |
| 52 base::Time now = base::Time::Now(); | 54 base::Time now = base::Time::Now(); |
| 53 | 55 |
| 54 extension_data[window_id].bounds = bounds; | 56 extension_data[window_id].bounds = bounds; |
| 57 extension_data[window_id].window_state = window_state; |
| 55 extension_data[window_id].last_change = now; | 58 extension_data[window_id].last_change = now; |
| 56 | 59 |
| 57 if (extension_data.size() > kMaxCachedWindows) { | 60 if (extension_data.size() > kMaxCachedWindows) { |
| 58 ExtensionData::iterator oldest = extension_data.end(); | 61 ExtensionData::iterator oldest = extension_data.end(); |
| 59 // Too many windows in the cache, find the oldest one to remove. | 62 // Too many windows in the cache, find the oldest one to remove. |
| 60 for (ExtensionData::iterator it = extension_data.begin(); | 63 for (ExtensionData::iterator it = extension_data.begin(); |
| 61 it != extension_data.end(); ++it) { | 64 it != extension_data.end(); ++it) { |
| 62 // Don't expunge the window that was just added. | 65 // Don't expunge the window that was just added. |
| 63 if (it->first == window_id) continue; | 66 if (it->first == window_id) continue; |
| 64 | 67 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 92 | 95 |
| 93 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); | 96 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); |
| 94 for (ExtensionData::const_iterator it = extension_data.begin(), | 97 for (ExtensionData::const_iterator it = extension_data.begin(), |
| 95 eit = extension_data.end(); it != eit; ++it) { | 98 eit = extension_data.end(); it != eit; ++it) { |
| 96 base::DictionaryValue* value = new base::DictionaryValue; | 99 base::DictionaryValue* value = new base::DictionaryValue; |
| 97 const gfx::Rect& bounds = it->second.bounds; | 100 const gfx::Rect& bounds = it->second.bounds; |
| 98 value->SetInteger("x", bounds.x()); | 101 value->SetInteger("x", bounds.x()); |
| 99 value->SetInteger("y", bounds.y()); | 102 value->SetInteger("y", bounds.y()); |
| 100 value->SetInteger("w", bounds.width()); | 103 value->SetInteger("w", bounds.width()); |
| 101 value->SetInteger("h", bounds.height()); | 104 value->SetInteger("h", bounds.height()); |
| 105 value->SetInteger("state", it->second.window_state); |
| 102 value->SetString( | 106 value->SetString( |
| 103 "ts", base::Int64ToString(it->second.last_change.ToInternalValue())); | 107 "ts", base::Int64ToString(it->second.last_change.ToInternalValue())); |
| 104 dict->SetWithoutPathExpansion(it->first, value); | 108 dict->SetWithoutPathExpansion(it->first, value); |
| 105 } | 109 } |
| 106 prefs_->SetGeometryCache(extension_id, dict.Pass()); | 110 prefs_->SetGeometryCache(extension_id, dict.Pass()); |
| 107 } | 111 } |
| 108 } | 112 } |
| 109 | 113 |
| 110 bool ShellWindowGeometryCache::GetGeometry( | 114 bool ShellWindowGeometryCache::GetGeometry( |
| 111 const std::string& extension_id, | 115 const std::string& extension_id, |
| 112 const std::string& window_id, | 116 const std::string& window_id, |
| 113 gfx::Rect* bounds) const { | 117 gfx::Rect* bounds, |
| 118 ui::WindowShowState* window_state) const { |
| 114 | 119 |
| 115 std::map<std::string, ExtensionData>::const_iterator | 120 std::map<std::string, ExtensionData>::const_iterator |
| 116 extension_data_it = cache_.find(extension_id); | 121 extension_data_it = cache_.find(extension_id); |
| 117 | 122 |
| 118 // Not in the map means loading data for the extension didn't finish yet. | 123 // Not in the map means loading data for the extension didn't finish yet. |
| 119 if (extension_data_it == cache_.end()) | 124 if (extension_data_it == cache_.end()) |
| 120 return false; | 125 return false; |
| 121 | 126 |
| 122 ExtensionData::const_iterator window_data = extension_data_it->second.find( | 127 ExtensionData::const_iterator window_data = extension_data_it->second.find( |
| 123 window_id); | 128 window_id); |
| 124 | 129 |
| 125 if (window_data == extension_data_it->second.end()) | 130 if (window_data == extension_data_it->second.end()) |
| 126 return false; | 131 return false; |
| 127 | 132 |
| 128 *bounds = window_data->second.bounds; | 133 if (bounds) |
| 134 *bounds = window_data->second.bounds; |
| 135 if (window_state) |
| 136 *window_state = window_data->second.window_state; |
| 129 return true; | 137 return true; |
| 130 } | 138 } |
| 131 | 139 |
| 132 void ShellWindowGeometryCache::Observe( | 140 void ShellWindowGeometryCache::Observe( |
| 133 int type, const content::NotificationSource& source, | 141 int type, const content::NotificationSource& source, |
| 134 const content::NotificationDetails& details) { | 142 const content::NotificationDetails& details) { |
| 135 switch (type) { | 143 switch (type) { |
| 136 case chrome::NOTIFICATION_EXTENSION_LOADED: { | 144 case chrome::NOTIFICATION_EXTENSION_LOADED: { |
| 137 std::string extension_id = | 145 std::string extension_id = |
| 138 content::Details<const Extension>(details).ptr()->id(); | 146 content::Details<const Extension>(details).ptr()->id(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 164 prefs_->GetGeometryCache(extension_id); | 172 prefs_->GetGeometryCache(extension_id); |
| 165 if (!stored_windows) | 173 if (!stored_windows) |
| 166 return; | 174 return; |
| 167 | 175 |
| 168 for (base::DictionaryValue::Iterator it(*stored_windows); !it.IsAtEnd(); | 176 for (base::DictionaryValue::Iterator it(*stored_windows); !it.IsAtEnd(); |
| 169 it.Advance()) { | 177 it.Advance()) { |
| 170 // If the cache already contains geometry for this window, don't | 178 // If the cache already contains geometry for this window, don't |
| 171 // overwrite that information since it is probably the result of an | 179 // overwrite that information since it is probably the result of an |
| 172 // application starting up very quickly. | 180 // application starting up very quickly. |
| 173 const std::string& window_id = it.key(); | 181 const std::string& window_id = it.key(); |
| 174 ExtensionData::iterator cached_window = | 182 ExtensionData::iterator cached_window = extension_data.find(window_id); |
| 175 extension_data.find(window_id); | |
| 176 if (cached_window == extension_data.end()) { | 183 if (cached_window == extension_data.end()) { |
| 177 const base::DictionaryValue* stored_window; | 184 const base::DictionaryValue* stored_window; |
| 178 if (it.value().GetAsDictionary(&stored_window)) { | 185 if (it.value().GetAsDictionary(&stored_window)) { |
| 179 WindowData& window_data = extension_data[it.key()]; | 186 WindowData& window_data = extension_data[it.key()]; |
| 180 | 187 |
| 181 int i; | 188 int i; |
| 182 if (stored_window->GetInteger("x", &i)) | 189 if (stored_window->GetInteger("x", &i)) |
| 183 window_data.bounds.set_x(i); | 190 window_data.bounds.set_x(i); |
| 184 if (stored_window->GetInteger("y", &i)) | 191 if (stored_window->GetInteger("y", &i)) |
| 185 window_data.bounds.set_y(i); | 192 window_data.bounds.set_y(i); |
| 186 if (stored_window->GetInteger("w", &i)) | 193 if (stored_window->GetInteger("w", &i)) |
| 187 window_data.bounds.set_width(i); | 194 window_data.bounds.set_width(i); |
| 188 if (stored_window->GetInteger("h", &i)) | 195 if (stored_window->GetInteger("h", &i)) |
| 189 window_data.bounds.set_height(i); | 196 window_data.bounds.set_height(i); |
| 197 if (stored_window->GetInteger("state", &i)) { |
| 198 window_data.window_state = |
| 199 static_cast<ui::WindowShowState>(i); |
| 200 } |
| 190 std::string ts_as_string; | 201 std::string ts_as_string; |
| 191 if (stored_window->GetString("ts", &ts_as_string)) { | 202 if (stored_window->GetString("ts", &ts_as_string)) { |
| 192 int64 ts; | 203 int64 ts; |
| 193 if (base::StringToInt64(ts_as_string, &ts)) { | 204 if (base::StringToInt64(ts_as_string, &ts)) { |
| 194 window_data.last_change = base::Time::FromInternalValue(ts); | 205 window_data.last_change = base::Time::FromInternalValue(ts); |
| 195 } | 206 } |
| 196 } | 207 } |
| 197 } | 208 } |
| 198 } | 209 } |
| 199 } | 210 } |
| 200 } | 211 } |
| 201 | 212 |
| 202 void ShellWindowGeometryCache::OnExtensionUnloaded( | 213 void ShellWindowGeometryCache::OnExtensionUnloaded( |
| 203 const std::string& extension_id) { | 214 const std::string& extension_id) { |
| 204 SyncToStorage(); | 215 SyncToStorage(); |
| 205 cache_.erase(extension_id); | 216 cache_.erase(extension_id); |
| 206 } | 217 } |
| 207 | 218 |
| 208 } // namespace extensions | 219 } // namespace extensions |
| OLD | NEW |