| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/frame_host/navigation_entry_screenshot_manager.h" | 5 #include "content/browser/frame_host/navigation_entry_screenshot_manager.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/threading/worker_pool.h" | 8 #include "base/threading/worker_pool.h" |
| 9 #include "content/browser/frame_host/navigation_controller_impl.h" | 9 #include "content/browser/frame_host/navigation_controller_impl.h" |
| 10 #include "content/browser/frame_host/navigation_entry_impl.h" | 10 #include "content/browser/frame_host/navigation_entry_impl.h" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 | 71 |
| 72 NavigationEntryScreenshotManager::~NavigationEntryScreenshotManager() { | 72 NavigationEntryScreenshotManager::~NavigationEntryScreenshotManager() { |
| 73 } | 73 } |
| 74 | 74 |
| 75 void NavigationEntryScreenshotManager::TakeScreenshot() { | 75 void NavigationEntryScreenshotManager::TakeScreenshot() { |
| 76 static bool overscroll_enabled = base::CommandLine::ForCurrentProcess()-> | 76 static bool overscroll_enabled = base::CommandLine::ForCurrentProcess()-> |
| 77 GetSwitchValueASCII(switches::kOverscrollHistoryNavigation) != "0"; | 77 GetSwitchValueASCII(switches::kOverscrollHistoryNavigation) != "0"; |
| 78 if (!overscroll_enabled) | 78 if (!overscroll_enabled) |
| 79 return; | 79 return; |
| 80 | 80 |
| 81 NavigationEntryImpl* entry = | 81 NavigationEntryImpl* entry = owner_->GetLastCommittedEntry(); |
| 82 NavigationEntryImpl::FromNavigationEntry(owner_->GetLastCommittedEntry()); | |
| 83 if (!entry) | 82 if (!entry) |
| 84 return; | 83 return; |
| 85 | 84 |
| 86 if (!owner_->delegate()->CanOverscrollContent()) | 85 if (!owner_->delegate()->CanOverscrollContent()) |
| 87 return; | 86 return; |
| 88 | 87 |
| 89 RenderViewHost* render_view_host = | 88 RenderViewHost* render_view_host = |
| 90 owner_->delegate()->GetRenderViewHost(); | 89 owner_->delegate()->GetRenderViewHost(); |
| 91 content::RenderWidgetHostView* view = render_view_host->GetView(); | 90 content::RenderWidgetHostView* view = render_view_host->GetView(); |
| 92 if (!view) | 91 if (!view) |
| 93 return; | 92 return; |
| 94 | 93 |
| 95 // Make sure screenshots aren't taken too frequently. | 94 // Make sure screenshots aren't taken too frequently. |
| 96 base::Time now = base::Time::Now(); | 95 base::Time now = base::Time::Now(); |
| 97 if (now - last_screenshot_time_ < | 96 if (now - last_screenshot_time_ < |
| 98 base::TimeDelta::FromMilliseconds(min_screenshot_interval_ms_)) { | 97 base::TimeDelta::FromMilliseconds(min_screenshot_interval_ms_)) { |
| 99 return; | 98 return; |
| 100 } | 99 } |
| 101 | 100 |
| 102 last_screenshot_time_ = now; | 101 last_screenshot_time_ = now; |
| 103 | 102 |
| 104 TakeScreenshotImpl(render_view_host, entry); | 103 TakeScreenshotImpl(render_view_host, entry); |
| 105 } | 104 } |
| 106 | 105 |
| 107 // Implemented here and not in NavigationEntry because this manager keeps track | 106 // Implemented here and not in NavigationEntry because this manager keeps track |
| 108 // of the total number of screen shots across all entries. | 107 // of the total number of screen shots across all entries. |
| 109 void NavigationEntryScreenshotManager::ClearAllScreenshots() { | 108 void NavigationEntryScreenshotManager::ClearAllScreenshots() { |
| 110 int count = owner_->GetEntryCount(); | 109 int count = owner_->GetEntryCount(); |
| 111 for (int i = 0; i < count; ++i) { | 110 for (int i = 0; i < count; ++i) { |
| 112 ClearScreenshot(NavigationEntryImpl::FromNavigationEntry( | 111 ClearScreenshot(owner_->GetEntryAtIndex(i)); |
| 113 owner_->GetEntryAtIndex(i))); | |
| 114 } | 112 } |
| 115 DCHECK_EQ(GetScreenshotCount(), 0); | 113 DCHECK_EQ(GetScreenshotCount(), 0); |
| 116 } | 114 } |
| 117 | 115 |
| 118 void NavigationEntryScreenshotManager::TakeScreenshotImpl( | 116 void NavigationEntryScreenshotManager::TakeScreenshotImpl( |
| 119 RenderViewHost* host, | 117 RenderViewHost* host, |
| 120 NavigationEntryImpl* entry) { | 118 NavigationEntryImpl* entry) { |
| 121 DCHECK(host && host->GetView()); | 119 DCHECK(host && host->GetView()); |
| 122 DCHECK(entry); | 120 DCHECK(entry); |
| 123 host->CopyFromBackingStore( | 121 host->CopyFromBackingStore( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 135 min_screenshot_interval_ms_ = interval_ms; | 133 min_screenshot_interval_ms_ = interval_ms; |
| 136 } | 134 } |
| 137 | 135 |
| 138 void NavigationEntryScreenshotManager::OnScreenshotTaken( | 136 void NavigationEntryScreenshotManager::OnScreenshotTaken( |
| 139 int unique_id, | 137 int unique_id, |
| 140 const SkBitmap& bitmap, | 138 const SkBitmap& bitmap, |
| 141 ReadbackResponse response) { | 139 ReadbackResponse response) { |
| 142 NavigationEntryImpl* entry = NULL; | 140 NavigationEntryImpl* entry = NULL; |
| 143 int entry_count = owner_->GetEntryCount(); | 141 int entry_count = owner_->GetEntryCount(); |
| 144 for (int i = 0; i < entry_count; ++i) { | 142 for (int i = 0; i < entry_count; ++i) { |
| 145 NavigationEntry* iter = owner_->GetEntryAtIndex(i); | 143 NavigationEntryImpl* iter = owner_->GetEntryAtIndex(i); |
| 146 if (iter->GetUniqueID() == unique_id) { | 144 if (iter->GetUniqueID() == unique_id) { |
| 147 entry = NavigationEntryImpl::FromNavigationEntry(iter); | 145 entry = iter; |
| 148 break; | 146 break; |
| 149 } | 147 } |
| 150 } | 148 } |
| 151 | 149 |
| 152 if (!entry) { | 150 if (!entry) { |
| 153 LOG(ERROR) << "Invalid entry with unique id: " << unique_id; | 151 LOG(ERROR) << "Invalid entry with unique id: " << unique_id; |
| 154 return; | 152 return; |
| 155 } | 153 } |
| 156 | 154 |
| 157 if ((response != READBACK_SUCCESS) || bitmap.empty() || bitmap.isNull()) { | 155 if ((response != READBACK_SUCCESS) || bitmap.empty() || bitmap.isNull()) { |
| 158 if (!ClearScreenshot(entry)) | 156 if (!ClearScreenshot(entry)) |
| 159 OnScreenshotSet(entry); | 157 OnScreenshotSet(entry); |
| 160 return; | 158 return; |
| 161 } | 159 } |
| 162 | 160 |
| 163 scoped_refptr<ScreenshotData> screenshot = new ScreenshotData(); | 161 scoped_refptr<ScreenshotData> screenshot = new ScreenshotData(); |
| 164 screenshot->EncodeScreenshot( | 162 screenshot->EncodeScreenshot( |
| 165 bitmap, | 163 bitmap, |
| 166 base::Bind(&NavigationEntryScreenshotManager::OnScreenshotEncodeComplete, | 164 base::Bind(&NavigationEntryScreenshotManager::OnScreenshotEncodeComplete, |
| 167 screenshot_factory_.GetWeakPtr(), | 165 screenshot_factory_.GetWeakPtr(), |
| 168 unique_id, | 166 unique_id, |
| 169 screenshot)); | 167 screenshot)); |
| 170 } | 168 } |
| 171 | 169 |
| 172 int NavigationEntryScreenshotManager::GetScreenshotCount() const { | 170 int NavigationEntryScreenshotManager::GetScreenshotCount() const { |
| 173 int screenshot_count = 0; | 171 int screenshot_count = 0; |
| 174 int entry_count = owner_->GetEntryCount(); | 172 int entry_count = owner_->GetEntryCount(); |
| 175 for (int i = 0; i < entry_count; ++i) { | 173 for (int i = 0; i < entry_count; ++i) { |
| 176 NavigationEntryImpl* entry = | 174 NavigationEntryImpl* entry = owner_->GetEntryAtIndex(i); |
| 177 NavigationEntryImpl::FromNavigationEntry(owner_->GetEntryAtIndex(i)); | |
| 178 if (entry->screenshot().get()) | 175 if (entry->screenshot().get()) |
| 179 screenshot_count++; | 176 screenshot_count++; |
| 180 } | 177 } |
| 181 return screenshot_count; | 178 return screenshot_count; |
| 182 } | 179 } |
| 183 | 180 |
| 184 void NavigationEntryScreenshotManager::OnScreenshotEncodeComplete( | 181 void NavigationEntryScreenshotManager::OnScreenshotEncodeComplete( |
| 185 int unique_id, | 182 int unique_id, |
| 186 scoped_refptr<ScreenshotData> screenshot) { | 183 scoped_refptr<ScreenshotData> screenshot) { |
| 187 NavigationEntryImpl* entry = NULL; | 184 NavigationEntryImpl* entry = NULL; |
| 188 int entry_count = owner_->GetEntryCount(); | 185 int entry_count = owner_->GetEntryCount(); |
| 189 for (int i = 0; i < entry_count; ++i) { | 186 for (int i = 0; i < entry_count; ++i) { |
| 190 NavigationEntry* iter = owner_->GetEntryAtIndex(i); | 187 NavigationEntryImpl* iter = owner_->GetEntryAtIndex(i); |
| 191 if (iter->GetUniqueID() == unique_id) { | 188 if (iter->GetUniqueID() == unique_id) { |
| 192 entry = NavigationEntryImpl::FromNavigationEntry(iter); | 189 entry = iter; |
| 193 break; | 190 break; |
| 194 } | 191 } |
| 195 } | 192 } |
| 196 if (!entry) | 193 if (!entry) |
| 197 return; | 194 return; |
| 198 entry->SetScreenshotPNGData(screenshot->data()); | 195 entry->SetScreenshotPNGData(screenshot->data()); |
| 199 OnScreenshotSet(entry); | 196 OnScreenshotSet(entry); |
| 200 } | 197 } |
| 201 | 198 |
| 202 void NavigationEntryScreenshotManager::OnScreenshotSet( | 199 void NavigationEntryScreenshotManager::OnScreenshotSet( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 217 void NavigationEntryScreenshotManager::PurgeScreenshotsIfNecessary() { | 214 void NavigationEntryScreenshotManager::PurgeScreenshotsIfNecessary() { |
| 218 // Allow only a certain number of entries to keep screenshots. | 215 // Allow only a certain number of entries to keep screenshots. |
| 219 const int kMaxScreenshots = 10; | 216 const int kMaxScreenshots = 10; |
| 220 int screenshot_count = GetScreenshotCount(); | 217 int screenshot_count = GetScreenshotCount(); |
| 221 if (screenshot_count < kMaxScreenshots) | 218 if (screenshot_count < kMaxScreenshots) |
| 222 return; | 219 return; |
| 223 | 220 |
| 224 const int current = owner_->GetCurrentEntryIndex(); | 221 const int current = owner_->GetCurrentEntryIndex(); |
| 225 const int num_entries = owner_->GetEntryCount(); | 222 const int num_entries = owner_->GetEntryCount(); |
| 226 int available_slots = kMaxScreenshots; | 223 int available_slots = kMaxScreenshots; |
| 227 if (NavigationEntryImpl::FromNavigationEntry(owner_->GetEntryAtIndex(current)) | 224 if (owner_->GetEntryAtIndex(current)->screenshot().get()) { |
| 228 ->screenshot().get()) { | |
| 229 --available_slots; | 225 --available_slots; |
| 230 } | 226 } |
| 231 | 227 |
| 232 // Keep screenshots closer to the current navigation entry, and purge the ones | 228 // Keep screenshots closer to the current navigation entry, and purge the ones |
| 233 // that are farther away from it. So in each step, look at the entries at | 229 // that are farther away from it. So in each step, look at the entries at |
| 234 // each offset on both the back and forward history, and start counting them | 230 // each offset on both the back and forward history, and start counting them |
| 235 // to make sure that the correct number of screenshots are kept in memory. | 231 // to make sure that the correct number of screenshots are kept in memory. |
| 236 // Note that it is possible for some entries to be missing screenshots (e.g. | 232 // Note that it is possible for some entries to be missing screenshots (e.g. |
| 237 // when taking the screenshot failed for some reason). So there may be a state | 233 // when taking the screenshot failed for some reason). So there may be a state |
| 238 // where there are a lot of entries in the back history, but none of them has | 234 // where there are a lot of entries in the back history, but none of them has |
| 239 // any screenshot. In such cases, keep the screenshots for |kMaxScreenshots| | 235 // any screenshot. In such cases, keep the screenshots for |kMaxScreenshots| |
| 240 // entries in the forward history list. | 236 // entries in the forward history list. |
| 241 int back = current - 1; | 237 int back = current - 1; |
| 242 int forward = current + 1; | 238 int forward = current + 1; |
| 243 while (available_slots > 0 && (back >= 0 || forward < num_entries)) { | 239 while (available_slots > 0 && (back >= 0 || forward < num_entries)) { |
| 244 if (back >= 0) { | 240 if (back >= 0) { |
| 245 NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( | 241 NavigationEntryImpl* entry = owner_->GetEntryAtIndex(back); |
| 246 owner_->GetEntryAtIndex(back)); | |
| 247 if (entry->screenshot().get()) | 242 if (entry->screenshot().get()) |
| 248 --available_slots; | 243 --available_slots; |
| 249 --back; | 244 --back; |
| 250 } | 245 } |
| 251 | 246 |
| 252 if (available_slots > 0 && forward < num_entries) { | 247 if (available_slots > 0 && forward < num_entries) { |
| 253 NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( | 248 NavigationEntryImpl* entry = owner_->GetEntryAtIndex(forward); |
| 254 owner_->GetEntryAtIndex(forward)); | |
| 255 if (entry->screenshot().get()) | 249 if (entry->screenshot().get()) |
| 256 --available_slots; | 250 --available_slots; |
| 257 ++forward; | 251 ++forward; |
| 258 } | 252 } |
| 259 } | 253 } |
| 260 | 254 |
| 261 // Purge any screenshot at |back| or lower indices, and |forward| or higher | 255 // Purge any screenshot at |back| or lower indices, and |forward| or higher |
| 262 // indices. | 256 // indices. |
| 263 while (screenshot_count > kMaxScreenshots && back >= 0) { | 257 while (screenshot_count > kMaxScreenshots && back >= 0) { |
| 264 NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( | 258 NavigationEntryImpl* entry = owner_->GetEntryAtIndex(back); |
| 265 owner_->GetEntryAtIndex(back)); | |
| 266 if (ClearScreenshot(entry)) | 259 if (ClearScreenshot(entry)) |
| 267 --screenshot_count; | 260 --screenshot_count; |
| 268 --back; | 261 --back; |
| 269 } | 262 } |
| 270 | 263 |
| 271 while (screenshot_count > kMaxScreenshots && forward < num_entries) { | 264 while (screenshot_count > kMaxScreenshots && forward < num_entries) { |
| 272 NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( | 265 NavigationEntryImpl* entry = owner_->GetEntryAtIndex(forward); |
| 273 owner_->GetEntryAtIndex(forward)); | |
| 274 if (ClearScreenshot(entry)) | 266 if (ClearScreenshot(entry)) |
| 275 --screenshot_count; | 267 --screenshot_count; |
| 276 ++forward; | 268 ++forward; |
| 277 } | 269 } |
| 278 CHECK_GE(screenshot_count, 0); | 270 CHECK_GE(screenshot_count, 0); |
| 279 CHECK_LE(screenshot_count, kMaxScreenshots); | 271 CHECK_LE(screenshot_count, kMaxScreenshots); |
| 280 } | 272 } |
| 281 | 273 |
| 282 } // namespace content | 274 } // namespace content |
| OLD | NEW |