| Index: chrome/browser/renderer_host/render_view_host.cc
|
| ===================================================================
|
| --- chrome/browser/renderer_host/render_view_host.cc (revision 46794)
|
| +++ chrome/browser/renderer_host/render_view_host.cc (working copy)
|
| @@ -15,11 +15,14 @@
|
| #include "base/string_util.h"
|
| #include "base/time.h"
|
| #include "base/waitable_event.h"
|
| +#include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/child_process_security_policy.h"
|
| #include "chrome/browser/cross_site_request_manager.h"
|
| +#include "chrome/browser/chrome_thread.h"
|
| #include "chrome/browser/debugger/devtools_manager.h"
|
| #include "chrome/browser/dom_operation_notification_details.h"
|
| #include "chrome/browser/extensions/extension_message_service.h"
|
| +#include "chrome/browser/icon_manager.h"
|
| #include "chrome/browser/metrics/user_metrics.h"
|
| #include "chrome/browser/notifications/desktop_notification_service.h"
|
| #include "chrome/browser/profile.h"
|
| @@ -39,6 +42,7 @@
|
| #include "chrome/common/thumbnail_score.h"
|
| #include "chrome/common/translate_errors.h"
|
| #include "chrome/common/url_constants.h"
|
| +#include "gfx/codec/png_codec.h"
|
| #include "gfx/native_widget_types.h"
|
| #include "net/base/net_util.h"
|
| #include "third_party/skia/include/core/SkBitmap.h"
|
| @@ -756,6 +760,7 @@
|
| OnMsgGoToEntryAtOffset)
|
| IPC_MESSAGE_HANDLER(ViewHostMsg_SetTooltipText, OnMsgSetTooltipText)
|
| IPC_MESSAGE_HANDLER(ViewHostMsg_RunFileChooser, OnMsgRunFileChooser)
|
| + IPC_MESSAGE_HANDLER(ViewHostMsg_ChooseIconForFiles, OnMsgChooseIconForFiles)
|
| IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunJavaScriptMessage,
|
| OnMsgRunJavaScriptMessage)
|
| IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunBeforeUnloadConfirm,
|
| @@ -1315,6 +1320,115 @@
|
| delegate_->RunFileChooser(params);
|
| }
|
|
|
| +// Manages cancelable icon loading.
|
| +class IconRequestProvider : public CancelableRequestProvider {
|
| + public:
|
| + typedef Callback2<int, SkBitmap*>::Type RequestCallbackType;
|
| + typedef CancelableRequest<RequestCallbackType> RequestType;
|
| +
|
| + Handle Start(int request_id, const std::vector<FilePath>& filenames,
|
| + CancelableRequestConsumerBase* consumer,
|
| + RequestCallbackType* callback);
|
| +
|
| + private:
|
| + CancelableRequestConsumerT<int, 0> consumer_;
|
| +};
|
| +
|
| +// Helper for OnMsgChooseIconForFiles().
|
| +// This instance runs in the UI thread.
|
| +class IconRequestBackend : public
|
| + base::RefCountedThreadSafe<IconRequestBackend> {
|
| + public:
|
| + explicit IconRequestBackend(
|
| + scoped_refptr<IconRequestProvider::RequestType> request,
|
| + CancelableRequestConsumerBase* consumer,
|
| + int request_id,
|
| + const std::vector<FilePath>& filenames)
|
| + : request_(request),
|
| + consumer_(consumer),
|
| + request_id_(request_id),
|
| + filenames_(filenames) { }
|
| +
|
| + void Run() {
|
| + if (request_->canceled()) {
|
| + Release();
|
| + return;
|
| + }
|
| +
|
| + IconManager* im = g_browser_process->icon_manager();
|
| + if (filenames_.size() <= 0) {
|
| + Reply(NULL);
|
| + } else {
|
| + // TODO(tkent): Load an icon representing `multiple files' in a case of
|
| + // filenames_.size() > 1.
|
| + SkBitmap* icon = im->LookupIcon(filenames_[0], IconLoader::NORMAL);
|
| + if (icon) {
|
| + Reply(icon);
|
| + return;
|
| + }
|
| + im->LoadIcon(filenames_[0], IconLoader::NORMAL, consumer_,
|
| + NewCallback(this, &IconRequestBackend::OnIconLoaded));
|
| + }
|
| + }
|
| +
|
| + private:
|
| + ~IconRequestBackend() { }
|
| +
|
| + void Reply(SkBitmap* icon) {
|
| + request_->ForwardResult(Tuple2<int, SkBitmap*>(request_id_, icon));
|
| + Release();
|
| + }
|
| +
|
| + void OnIconLoaded(IconManager::Handle handle, SkBitmap* icon) {
|
| + Reply(icon);
|
| + }
|
| +
|
| + scoped_refptr<IconRequestProvider::RequestType> request_;
|
| + // CancelableRequestConsumer for IconManager.
|
| + CancelableRequestConsumerBase* consumer_;
|
| + // Copy of a ViewHostMsg_IconForFiles arguemnt.
|
| + int request_id_;
|
| + // Copy of a ViewHostMsg_IconForFiles arguemnt.
|
| + const std::vector<FilePath> filenames_;
|
| +
|
| + friend class base::RefCountedThreadSafe<IconRequestBackend>;
|
| +};
|
| +
|
| +IconRequestProvider::Handle IconRequestProvider::Start(
|
| + int request_id,
|
| + const std::vector<FilePath>& filenames,
|
| + CancelableRequestConsumerBase* consumer,
|
| + RequestCallbackType* callback) {
|
| + scoped_refptr<RequestType> request(new RequestType(callback));
|
| + AddRequest(request, consumer);
|
| +
|
| + IconRequestBackend* backend =
|
| + new IconRequestBackend(request, &consumer_, request_id, filenames);
|
| + backend->AddRef();
|
| + // We need to switch to the UI thread because IconManager works
|
| + // only in the UI thread.
|
| + ChromeThread::PostTask(ChromeThread::UI, FROM_HERE,
|
| + NewRunnableMethod(backend, &IconRequestBackend::Run));
|
| + return request->handle();
|
| +}
|
| +
|
| +void RenderViewHost::OnIconLoaded(int request_id, SkBitmap* icon) {
|
| + std::vector<unsigned char> png_data;
|
| + gfx::PNGCodec::EncodeBGRASkBitmap(*icon, false, &png_data);
|
| + Send(new ViewMsg_ChooseIconForFilesResponse(
|
| + routing_id(), request_id, png_data));
|
| + // No need to delete |icon|. It is owned by IconManager.
|
| +}
|
| +
|
| +void RenderViewHost::OnMsgChooseIconForFiles(
|
| + int request_id, const std::vector<FilePath>& filenames) {
|
| + if (icon_request_provider_.get() == NULL) {
|
| + icon_request_provider_.reset(new IconRequestProvider());
|
| + }
|
| + icon_request_provider_->Start(request_id, filenames, &cancelable_consumer_,
|
| + NewCallback(this, &RenderViewHost::OnIconLoaded));
|
| +}
|
| +
|
| void RenderViewHost::OnMsgRunJavaScriptMessage(
|
| const std::wstring& message,
|
| const std::wstring& default_prompt,
|
|
|