| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/automation/automation_provider_observers.h" | 5 #include "chrome/browser/automation/automation_provider_observers.h" |
| 6 | 6 |
| 7 #include <deque> | 7 #include <deque> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 1874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1885 reply_message_.release()).SendSuccess(NULL); | 1885 reply_message_.release()).SendSuccess(NULL); |
| 1886 } | 1886 } |
| 1887 delete this; | 1887 delete this; |
| 1888 } else { | 1888 } else { |
| 1889 NOTREACHED(); | 1889 NOTREACHED(); |
| 1890 } | 1890 } |
| 1891 } | 1891 } |
| 1892 | 1892 |
| 1893 PageSnapshotTaker::PageSnapshotTaker(AutomationProvider* automation, | 1893 PageSnapshotTaker::PageSnapshotTaker(AutomationProvider* automation, |
| 1894 IPC::Message* reply_message, | 1894 IPC::Message* reply_message, |
| 1895 TabContentsWrapper* tab_contents, | 1895 RenderViewHost* render_view, |
| 1896 const FilePath& path) | 1896 const FilePath& path) |
| 1897 : automation_(automation->AsWeakPtr()), | 1897 : automation_(automation->AsWeakPtr()), |
| 1898 reply_message_(reply_message), | 1898 reply_message_(reply_message), |
| 1899 tab_contents_(tab_contents), | 1899 render_view_(render_view), |
| 1900 image_path_(path) { | 1900 image_path_(path), |
| 1901 registrar_.Add(this, chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN, | 1901 received_width_(false) {} |
| 1902 content::NotificationService::AllSources()); | |
| 1903 } | |
| 1904 | 1902 |
| 1905 PageSnapshotTaker::~PageSnapshotTaker() {} | 1903 PageSnapshotTaker::~PageSnapshotTaker() {} |
| 1906 | 1904 |
| 1907 void PageSnapshotTaker::Start() { | 1905 void PageSnapshotTaker::Start() { |
| 1908 StartObserving(tab_contents_->automation_tab_helper()); | 1906 ExecuteScript(L"window.domAutomationController.send(document.width);"); |
| 1909 tab_contents_->automation_tab_helper()->SnapshotEntirePage(); | |
| 1910 } | 1907 } |
| 1911 | 1908 |
| 1912 void PageSnapshotTaker::OnSnapshotEntirePageACK( | 1909 void PageSnapshotTaker::OnDomOperationCompleted(const std::string& json) { |
| 1913 bool success, | 1910 int dimension; |
| 1914 const std::vector<unsigned char>& png_data, | 1911 if (!base::StringToInt(json, &dimension)) { |
| 1915 const std::string& error_msg) { | 1912 SendMessage(false, "could not parse received dimensions: " + json); |
| 1916 bool overall_success = success; | 1913 } else if (!received_width_) { |
| 1917 std::string overall_error_msg = error_msg; | 1914 received_width_ = true; |
| 1918 if (success) { | 1915 entire_page_size_.set_width(dimension); |
| 1919 base::ThreadRestrictions::ScopedAllowIO allow_io; | 1916 |
| 1920 int bytes_written = file_util::WriteFile(image_path_, | 1917 ExecuteScript(L"window.domAutomationController.send(document.height);"); |
| 1921 reinterpret_cast<const char*>(&png_data[0]), png_data.size()); | 1918 } else { |
| 1922 overall_success = (bytes_written == static_cast<int>(png_data.size())); | 1919 entire_page_size_.set_height(dimension); |
| 1923 if (!overall_success) | 1920 |
| 1924 overall_error_msg = "could not write snapshot to disk"; | 1921 ThumbnailGenerator* generator = |
| 1922 g_browser_process->GetThumbnailGenerator(); |
| 1923 ThumbnailGenerator::ThumbnailReadyCallback callback = |
| 1924 base::Bind(&PageSnapshotTaker::OnSnapshotTaken, base::Unretained(this)); |
| 1925 // Don't actually start the thumbnail generator, this leads to crashes on |
| 1926 // Mac, crbug.com/62986. Instead, just hook the generator to the |
| 1927 // RenderViewHost manually. |
| 1928 |
| 1929 generator->MonitorRenderer(render_view_, true); |
| 1930 generator->AskForSnapshot(render_view_, false, callback, |
| 1931 entire_page_size_, entire_page_size_); |
| 1925 } | 1932 } |
| 1926 SendMessage(overall_success, overall_error_msg); | |
| 1927 } | 1933 } |
| 1928 | 1934 |
| 1929 void PageSnapshotTaker::Observe(int type, | 1935 void PageSnapshotTaker::OnModalDialogShown() { |
| 1930 const content::NotificationSource& source, | |
| 1931 const content::NotificationDetails& details) { | |
| 1932 SendMessage(false, "a modal dialog is active"); | 1936 SendMessage(false, "a modal dialog is active"); |
| 1933 } | 1937 } |
| 1934 | 1938 |
| 1939 void PageSnapshotTaker::OnSnapshotTaken(const SkBitmap& bitmap) { |
| 1940 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 1941 std::vector<unsigned char> png_data; |
| 1942 SkAutoLockPixels lock_input(bitmap); |
| 1943 bool success = gfx::PNGCodec::Encode( |
| 1944 reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)), |
| 1945 gfx::PNGCodec::FORMAT_BGRA, |
| 1946 gfx::Size(bitmap.width(), bitmap.height()), |
| 1947 bitmap.rowBytes(), |
| 1948 true, // discard_transparency |
| 1949 std::vector<gfx::PNGCodec::Comment>(), |
| 1950 &png_data); |
| 1951 std::string error_msg; |
| 1952 if (!success) { |
| 1953 error_msg = "could not encode bitmap as PNG"; |
| 1954 } else { |
| 1955 int bytes_written = file_util::WriteFile(image_path_, |
| 1956 reinterpret_cast<char*>(&png_data[0]), png_data.size()); |
| 1957 success = bytes_written == static_cast<int>(png_data.size()); |
| 1958 if (!success) |
| 1959 error_msg = "could not write snapshot to disk"; |
| 1960 } |
| 1961 SendMessage(success, error_msg); |
| 1962 } |
| 1963 |
| 1964 void PageSnapshotTaker::ExecuteScript(const std::wstring& javascript) { |
| 1965 std::wstring set_automation_id; |
| 1966 base::SStringPrintf( |
| 1967 &set_automation_id, |
| 1968 L"window.domAutomationController.setAutomationId(%d);", |
| 1969 reply_message_->routing_id()); |
| 1970 |
| 1971 render_view_->ExecuteJavascriptInWebFrame(string16(), |
| 1972 WideToUTF16Hack(set_automation_id)); |
| 1973 render_view_->ExecuteJavascriptInWebFrame(string16(), |
| 1974 WideToUTF16Hack(javascript)); |
| 1975 } |
| 1935 | 1976 |
| 1936 void PageSnapshotTaker::SendMessage(bool success, | 1977 void PageSnapshotTaker::SendMessage(bool success, |
| 1937 const std::string& error_msg) { | 1978 const std::string& error_msg) { |
| 1938 if (automation_) { | 1979 if (automation_) { |
| 1939 if (success) { | 1980 if (success) { |
| 1940 AutomationJSONReply(automation_, reply_message_.release()) | 1981 AutomationJSONReply(automation_, reply_message_.release()) |
| 1941 .SendSuccess(NULL); | 1982 .SendSuccess(NULL); |
| 1942 } else { | 1983 } else { |
| 1943 AutomationJSONReply(automation_, reply_message_.release()) | 1984 AutomationJSONReply(automation_, reply_message_.release()) |
| 1944 .SendError("Failed to take snapshot of page: " + error_msg); | 1985 .SendError("Failed to take snapshot of page: " + error_msg); |
| (...skipping 953 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2898 if (automation_) { | 2939 if (automation_) { |
| 2899 AutomationJSONReply(automation_, reply_message_.release()) | 2940 AutomationJSONReply(automation_, reply_message_.release()) |
| 2900 .SendSuccess(NULL); | 2941 .SendSuccess(NULL); |
| 2901 } | 2942 } |
| 2902 delete this; | 2943 delete this; |
| 2903 } | 2944 } |
| 2904 } else { | 2945 } else { |
| 2905 NOTREACHED(); | 2946 NOTREACHED(); |
| 2906 } | 2947 } |
| 2907 } | 2948 } |
| OLD | NEW |