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

Unified Diff: chrome/browser/ui/ash/screenshot_taker.cc

Issue 14027009: Crash when taking screenshot onto Chrome OS Google Drive (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: minor Created 7 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/ash/screenshot_taker.h ('k') | chrome/browser/ui/ash/screenshot_taker_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/ash/screenshot_taker.cc
diff --git a/chrome/browser/ui/ash/screenshot_taker.cc b/chrome/browser/ui/ash/screenshot_taker.cc
index e53f54349e43804bbe1b8d9a1ee32626e579a25c..5d409013160adf295fc463c34ef726049ff960b3 100644
--- a/chrome/browser/ui/ash/screenshot_taker.cc
+++ b/chrome/browser/ui/ash/screenshot_taker.cc
@@ -21,6 +21,7 @@
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/webui/screenshot_source.h"
#include "chrome/browser/ui/window_snapshot/window_snapshot.h"
#include "content/public/browser/browser_thread.h"
@@ -43,6 +44,8 @@ namespace {
// more than 1000 to prevent the conflict of filenames.
const int kScreenshotMinimumIntervalInMS = 1000;
+const char kNotificationId[] = "screenshot";
+
const char kNotificationOriginUrl[] = "chrome://screenshot";
// Delegate for a notification. This class has two roles: to implement callback
@@ -50,11 +53,9 @@ const char kNotificationOriginUrl[] = "chrome://screenshot";
// notification.
class ScreenshotTakerNotificationDelegate : public NotificationDelegate {
public:
- ScreenshotTakerNotificationDelegate(const std::string& id_text,
- bool success,
+ ScreenshotTakerNotificationDelegate(bool success,
const base::FilePath& screenshot_path)
- : id_text_(id_text),
- success_(success),
+ : success_(success),
screenshot_path_(screenshot_path) {
}
@@ -71,7 +72,9 @@ class ScreenshotTakerNotificationDelegate : public NotificationDelegate {
// TODO(sschmitz): perhaps add similar action for Windows.
#endif
}
- virtual std::string id() const OVERRIDE { return id_text_; }
+ virtual std::string id() const OVERRIDE {
+ return std::string(kNotificationId);
+ }
virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE {
return NULL;
}
@@ -79,7 +82,6 @@ class ScreenshotTakerNotificationDelegate : public NotificationDelegate {
private:
virtual ~ScreenshotTakerNotificationDelegate() {}
- const std::string id_text_;
const bool success_;
const base::FilePath screenshot_path_;
@@ -92,16 +94,17 @@ typedef base::Callback<
void SaveScreenshotInternal(const ShowNotificationCallback& callback,
const base::FilePath& screenshot_path,
+ const base::FilePath& local_path,
scoped_refptr<base::RefCountedBytes> png_data) {
DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
- DCHECK(!screenshot_path.empty());
+ DCHECK(!local_path.empty());
ScreenshotTakerObserver::Result result =
ScreenshotTakerObserver::SCREENSHOT_SUCCESS;
if (static_cast<size_t>(file_util::WriteFile(
- screenshot_path,
+ local_path,
reinterpret_cast<char*>(&(png_data->data()[0])),
png_data->size())) != png_data->size()) {
- LOG(ERROR) << "Failed to save to " << screenshot_path.value();
+ LOG(ERROR) << "Failed to save to " << local_path.value();
result = ScreenshotTakerObserver::SCREENSHOT_WRITE_FILE_FAILED;
}
content::BrowserThread::PostTask(
@@ -125,25 +128,29 @@ void SaveScreenshot(const ShowNotificationCallback& callback,
screenshot_path));
return;
}
- SaveScreenshotInternal(callback, screenshot_path, png_data);
+ SaveScreenshotInternal(callback, screenshot_path, screenshot_path, png_data);
}
// TODO(kinaba): crbug.com/140425, remove this ungly #ifdef dispatch.
#if defined(OS_CHROMEOS)
void SaveScreenshotToDrive(const ShowNotificationCallback& callback,
+ const base::FilePath& screenshot_path,
scoped_refptr<base::RefCountedBytes> png_data,
drive::DriveFileError error,
const base::FilePath& local_path) {
+ // |screenshot_path| is used in the notification callback.
+ // |local_path| is a temporary file in a hidden cache directory used for
+ // internal work generated by drive::util::PrepareWritableFileAndRun.
if (error != drive::DRIVE_FILE_OK) {
LOG(ERROR) << "Failed to write screenshot image to Google Drive: " << error;
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(callback,
ScreenshotTakerObserver::SCREENSHOT_CREATE_FILE_FAILED,
- local_path));
+ screenshot_path));
return;
}
- SaveScreenshotInternal(callback, local_path, png_data);
+ SaveScreenshotInternal(callback, screenshot_path, local_path, png_data);
}
void EnsureDirectoryExistsCallback(
@@ -159,7 +166,10 @@ void EnsureDirectoryExistsCallback(
drive::util::PrepareWritableFileAndRun(
profile,
screenshot_path,
- base::Bind(&SaveScreenshotToDrive, callback, png_data));
+ base::Bind(&SaveScreenshotToDrive,
+ callback,
+ screenshot_path,
+ png_data));
} else {
LOG(ERROR) << "Failed to ensure the existence of the specified directory "
<< "in Google Drive: " << error;
@@ -223,10 +233,9 @@ bool GrabWindowSnapshot(aura::Window* window,
} // namespace
-ScreenshotTaker::ScreenshotTaker(Profile* profile)
- : profile_(profile),
- ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {
- DCHECK(profile_);
+ScreenshotTaker::ScreenshotTaker()
+ : ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)),
+ profile_for_test_(NULL) {
}
ScreenshotTaker::~ScreenshotTaker() {
@@ -265,7 +274,7 @@ void ScreenshotTaker::HandleTakeScreenshotForAllRootWindows() {
if (GrabWindowSnapshot(root_window, rect, &png_data->data())) {
PostSaveScreenshotTask(
base::Bind(&ScreenshotTaker::ShowNotification, factory_.GetWeakPtr()),
- profile_,
+ GetProfile(),
screenshot_path,
png_data);
} else {
@@ -302,7 +311,7 @@ void ScreenshotTaker::HandleTakePartialScreenshot(
last_screenshot_timestamp_ = base::Time::Now();
PostSaveScreenshotTask(
base::Bind(&ScreenshotTaker::ShowNotification, factory_.GetWeakPtr()),
- profile_,
+ GetProfile(),
screenshot_path,
png_data);
} else {
@@ -326,9 +335,11 @@ void ScreenshotTaker::ShowNotification(
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
#if defined(OS_CHROMEOS)
// TODO(sschmitz): make this work for Windows.
- static int id = 0;
- std::string id_text = base::StringPrintf("screenshot_%3.3d", ++id);
- string16 replace_id = UTF8ToUTF16(id_text);
+ const std::string notification_id(kNotificationId);
+ // We cancel a previous screenshot notification, if any, to ensure we get
+ // a fresh notification pop-up.
+ g_browser_process->notification_ui_manager()->CancelById(notification_id);
+ const string16 replace_id(UTF8ToUTF16(notification_id));
bool success =
(screenshot_result == ScreenshotTakerObserver::SCREENSHOT_SUCCESS);
Notification notification(
@@ -346,10 +357,9 @@ void ScreenshotTaker::ShowNotification(
WebKit::WebTextDirectionDefault,
string16(),
replace_id,
- new ScreenshotTakerNotificationDelegate(id_text,
- success,
- screenshot_path));
- g_browser_process->notification_ui_manager()->Add(notification, profile_);
+ new ScreenshotTakerNotificationDelegate(success, screenshot_path));
+ g_browser_process->notification_ui_manager()->Add(notification,
+ GetProfile());
#endif
FOR_EACH_OBSERVER(ScreenshotTakerObserver, observers_,
@@ -368,12 +378,22 @@ bool ScreenshotTaker::HasObserver(ScreenshotTakerObserver* observer) const {
return observers_.HasObserver(observer);
}
+Profile* ScreenshotTaker::GetProfile() {
+ if (profile_for_test_)
+ return profile_for_test_;
+ return ProfileManager::GetDefaultProfileOrOffTheRecord();
sky 2013/04/22 15:01:19 The reason I wanted this code to take a Profile is
+}
+
void ScreenshotTaker::SetScreenshotDirectoryForTest(
const base::FilePath& directory) {
screenshot_directory_for_test_ = directory;
}
void ScreenshotTaker::SetScreenshotBasenameForTest(
- const std::string& basename){
+ const std::string& basename) {
screenshot_basename_for_test_ = basename;
}
+
+void ScreenshotTaker::SetScreenshotProfileForTest(Profile* profile) {
+ profile_for_test_ = profile;
+}
« no previous file with comments | « chrome/browser/ui/ash/screenshot_taker.h ('k') | chrome/browser/ui/ash/screenshot_taker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698