Index: content/browser/web_contents/web_contents_screenshot_manager.cc |
diff --git a/content/browser/web_contents/web_contents_screenshot_manager.cc b/content/browser/web_contents/web_contents_screenshot_manager.cc |
deleted file mode 100644 |
index d7becb5ddfed373ac5f893475f1cb45adf3d73a9..0000000000000000000000000000000000000000 |
--- a/content/browser/web_contents/web_contents_screenshot_manager.cc |
+++ /dev/null |
@@ -1,274 +0,0 @@ |
-// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "content/browser/web_contents/web_contents_screenshot_manager.h" |
- |
-#include "base/command_line.h" |
-#include "base/threading/worker_pool.h" |
-#include "content/browser/renderer_host/render_view_host_impl.h" |
-#include "content/browser/web_contents/navigation_controller_impl.h" |
-#include "content/browser/web_contents/navigation_entry_impl.h" |
-#include "content/browser/web_contents/web_contents_impl.h" |
-#include "content/public/browser/render_widget_host.h" |
-#include "content/public/browser/render_widget_host_view.h" |
-#include "content/public/common/content_switches.h" |
-#include "ui/gfx/codec/png_codec.h" |
- |
-namespace { |
- |
-// Minimum delay between taking screenshots. |
-const int kMinScreenshotIntervalMS = 1000; |
- |
-} |
- |
-namespace content { |
- |
-// Encodes an SkBitmap to PNG data in a worker thread. |
-class ScreenshotData : public base::RefCountedThreadSafe<ScreenshotData> { |
- public: |
- ScreenshotData() { |
- } |
- |
- void EncodeScreenshot(const SkBitmap& bitmap, base::Closure callback) { |
- if (!base::WorkerPool::PostTaskAndReply(FROM_HERE, |
- base::Bind(&ScreenshotData::EncodeOnWorker, |
- this, |
- bitmap), |
- callback, |
- true)) { |
- callback.Run(); |
- } |
- } |
- |
- scoped_refptr<base::RefCountedBytes> data() const { return data_; } |
- |
- private: |
- friend class base::RefCountedThreadSafe<ScreenshotData>; |
- virtual ~ScreenshotData() { |
- } |
- |
- void EncodeOnWorker(const SkBitmap& bitmap) { |
- std::vector<unsigned char> data; |
- if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &data)) |
- data_ = new base::RefCountedBytes(data); |
- } |
- |
- scoped_refptr<base::RefCountedBytes> data_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ScreenshotData); |
-}; |
- |
-WebContentsScreenshotManager::WebContentsScreenshotManager( |
- NavigationControllerImpl* owner) |
- : owner_(owner), |
- screenshot_factory_(this), |
- min_screenshot_interval_ms_(kMinScreenshotIntervalMS) { |
-} |
- |
-WebContentsScreenshotManager::~WebContentsScreenshotManager() { |
-} |
- |
-void WebContentsScreenshotManager::TakeScreenshot() { |
- static bool overscroll_enabled = CommandLine::ForCurrentProcess()-> |
- GetSwitchValueASCII(switches::kOverscrollHistoryNavigation) != "0"; |
- if (!overscroll_enabled) |
- return; |
- |
- NavigationEntryImpl* entry = |
- NavigationEntryImpl::FromNavigationEntry(owner_->GetLastCommittedEntry()); |
- if (!entry) |
- return; |
- |
- RenderViewHost* render_view_host = |
- owner_->delegate()->GetRenderViewHost(); |
- if (!static_cast<RenderViewHostImpl*> |
- (render_view_host)->overscroll_controller()) { |
- return; |
- } |
- content::RenderWidgetHostView* view = render_view_host->GetView(); |
- if (!view) |
- return; |
- |
- // Make sure screenshots aren't taken too frequently. |
- base::Time now = base::Time::Now(); |
- if (now - last_screenshot_time_ < |
- base::TimeDelta::FromMilliseconds(min_screenshot_interval_ms_)) { |
- return; |
- } |
- |
- last_screenshot_time_ = now; |
- |
- TakeScreenshotImpl(render_view_host, entry); |
-} |
- |
-// Implemented here and not in NavigationEntry because this manager keeps track |
-// of the total number of screen shots across all entries. |
-void WebContentsScreenshotManager::ClearAllScreenshots() { |
- int count = owner_->GetEntryCount(); |
- for (int i = 0; i < count; ++i) { |
- ClearScreenshot(NavigationEntryImpl::FromNavigationEntry( |
- owner_->GetEntryAtIndex(i))); |
- } |
- DCHECK_EQ(GetScreenshotCount(), 0); |
-} |
- |
-void WebContentsScreenshotManager::TakeScreenshotImpl( |
- RenderViewHost* host, |
- NavigationEntryImpl* entry) { |
- DCHECK(host && host->GetView()); |
- DCHECK(entry); |
- host->CopyFromBackingStore(gfx::Rect(), |
- host->GetView()->GetViewBounds().size(), |
- base::Bind(&WebContentsScreenshotManager::OnScreenshotTaken, |
- screenshot_factory_.GetWeakPtr(), |
- entry->GetUniqueID())); |
-} |
- |
-void WebContentsScreenshotManager::SetMinScreenshotIntervalMS(int interval_ms) { |
- DCHECK_GE(interval_ms, 0); |
- min_screenshot_interval_ms_ = interval_ms; |
-} |
- |
-void WebContentsScreenshotManager::OnScreenshotTaken(int unique_id, |
- bool success, |
- const SkBitmap& bitmap) { |
- NavigationEntryImpl* entry = NULL; |
- int entry_count = owner_->GetEntryCount(); |
- for (int i = 0; i < entry_count; ++i) { |
- NavigationEntry* iter = owner_->GetEntryAtIndex(i); |
- if (iter->GetUniqueID() == unique_id) { |
- entry = NavigationEntryImpl::FromNavigationEntry(iter); |
- break; |
- } |
- } |
- |
- if (!entry) { |
- LOG(ERROR) << "Invalid entry with unique id: " << unique_id; |
- return; |
- } |
- |
- if (!success || bitmap.empty() || bitmap.isNull()) { |
- if (!ClearScreenshot(entry)) |
- OnScreenshotSet(entry); |
- return; |
- } |
- |
- scoped_refptr<ScreenshotData> screenshot = new ScreenshotData(); |
- screenshot->EncodeScreenshot( |
- bitmap, |
- base::Bind(&WebContentsScreenshotManager::OnScreenshotEncodeComplete, |
- screenshot_factory_.GetWeakPtr(), |
- unique_id, |
- screenshot)); |
-} |
- |
-int WebContentsScreenshotManager::GetScreenshotCount() const { |
- int screenshot_count = 0; |
- int entry_count = owner_->GetEntryCount(); |
- for (int i = 0; i < entry_count; ++i) { |
- NavigationEntryImpl* entry = |
- NavigationEntryImpl::FromNavigationEntry(owner_->GetEntryAtIndex(i)); |
- if (entry->screenshot().get()) |
- screenshot_count++; |
- } |
- return screenshot_count; |
-} |
- |
-void WebContentsScreenshotManager::OnScreenshotEncodeComplete( |
- int unique_id, |
- scoped_refptr<ScreenshotData> screenshot) { |
- NavigationEntryImpl* entry = NULL; |
- int entry_count = owner_->GetEntryCount(); |
- for (int i = 0; i < entry_count; ++i) { |
- NavigationEntry* iter = owner_->GetEntryAtIndex(i); |
- if (iter->GetUniqueID() == unique_id) { |
- entry = NavigationEntryImpl::FromNavigationEntry(iter); |
- break; |
- } |
- } |
- if (!entry) |
- return; |
- entry->SetScreenshotPNGData(screenshot->data()); |
- OnScreenshotSet(entry); |
-} |
- |
-void WebContentsScreenshotManager::OnScreenshotSet(NavigationEntryImpl* entry) { |
- if (entry->screenshot().get()) |
- PurgeScreenshotsIfNecessary(); |
-} |
- |
-bool WebContentsScreenshotManager::ClearScreenshot(NavigationEntryImpl* entry) { |
- if (!entry->screenshot().get()) |
- return false; |
- |
- entry->SetScreenshotPNGData(NULL); |
- return true; |
-} |
- |
-void WebContentsScreenshotManager::PurgeScreenshotsIfNecessary() { |
- // Allow only a certain number of entries to keep screenshots. |
- const int kMaxScreenshots = 10; |
- int screenshot_count = GetScreenshotCount(); |
- if (screenshot_count < kMaxScreenshots) |
- return; |
- |
- const int current = owner_->GetCurrentEntryIndex(); |
- const int num_entries = owner_->GetEntryCount(); |
- int available_slots = kMaxScreenshots; |
- if (NavigationEntryImpl::FromNavigationEntry(owner_->GetEntryAtIndex(current)) |
- ->screenshot().get()) { |
- --available_slots; |
- } |
- |
- // Keep screenshots closer to the current navigation entry, and purge the ones |
- // that are farther away from it. So in each step, look at the entries at |
- // each offset on both the back and forward history, and start counting them |
- // to make sure that the correct number of screenshots are kept in memory. |
- // Note that it is possible for some entries to be missing screenshots (e.g. |
- // when taking the screenshot failed for some reason). So there may be a state |
- // where there are a lot of entries in the back history, but none of them has |
- // any screenshot. In such cases, keep the screenshots for |kMaxScreenshots| |
- // entries in the forward history list. |
- int back = current - 1; |
- int forward = current + 1; |
- while (available_slots > 0 && (back >= 0 || forward < num_entries)) { |
- if (back >= 0) { |
- NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( |
- owner_->GetEntryAtIndex(back)); |
- if (entry->screenshot().get()) |
- --available_slots; |
- --back; |
- } |
- |
- if (available_slots > 0 && forward < num_entries) { |
- NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( |
- owner_->GetEntryAtIndex(forward)); |
- if (entry->screenshot().get()) |
- --available_slots; |
- ++forward; |
- } |
- } |
- |
- // Purge any screenshot at |back| or lower indices, and |forward| or higher |
- // indices. |
- while (screenshot_count > kMaxScreenshots && back >= 0) { |
- NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( |
- owner_->GetEntryAtIndex(back)); |
- if (ClearScreenshot(entry)) |
- --screenshot_count; |
- --back; |
- } |
- |
- while (screenshot_count > kMaxScreenshots && forward < num_entries) { |
- NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( |
- owner_->GetEntryAtIndex(forward)); |
- if (ClearScreenshot(entry)) |
- --screenshot_count; |
- ++forward; |
- } |
- CHECK_GE(screenshot_count, 0); |
- CHECK_LE(screenshot_count, kMaxScreenshots); |
-} |
- |
-} // namespace content |