Chromium Code Reviews| Index: chrome/browser/extensions/platform_app_host.cc |
| diff --git a/chrome/browser/extensions/platform_app_host.cc b/chrome/browser/extensions/platform_app_host.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f6546a69fa428c06dcad5ea36d4b6b5ba5ca9b16 |
| --- /dev/null |
| +++ b/chrome/browser/extensions/platform_app_host.cc |
| @@ -0,0 +1,186 @@ |
| +// Copyright (c) 2012 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 "chrome/browser/extensions/platform_app_host.h" |
| + |
| +#include <list> |
| + |
| +// TODO(benwells): review include list and forward decls |
| +#include "base/bind.h" |
| +#include "base/memory/singleton.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "base/message_loop.h" |
| +#include "base/metrics/histogram.h" |
| +#include "base/string_util.h" |
| +#include "base/utf_string_conversions.h" |
| +#include "chrome/browser/browser_shutdown.h" |
| +#include "chrome/browser/extensions/extension_process_manager.h" |
| +#include "chrome/browser/extensions/extension_service.h" |
| +#include "chrome/browser/extensions/extension_system.h" |
| +#include "chrome/browser/extensions/extension_tab_util.h" |
| +#include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h" |
| +#include "chrome/browser/ui/browser.h" |
| +#include "chrome/browser/ui/browser_list.h" |
| +#include "chrome/browser/ui/browser_window.h" |
| +#include "chrome/browser/ui/prefs/prefs_tab_helper.h" |
| +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
| +#include "chrome/common/chrome_constants.h" |
| +#include "chrome/common/chrome_notification_types.h" |
| +#include "chrome/common/chrome_view_type.h" |
| +#include "chrome/common/extensions/extension.h" |
| +#include "chrome/common/extensions/extension_constants.h" |
| +#include "chrome/common/extensions/extension_messages.h" |
| +#include "chrome/common/render_messages.h" |
| +#include "chrome/common/url_constants.h" |
| +#include "content/public/browser/content_browser_client.h" |
| +#include "content/public/browser/native_web_keyboard_event.h" |
| +#include "content/public/browser/notification_service.h" |
| +#include "content/public/browser/render_process_host.h" |
| +#include "content/public/browser/render_view_host.h" |
| +#include "content/public/browser/site_instance.h" |
| +#include "content/public/browser/web_contents.h" |
| +#include "content/public/browser/web_contents_view.h" |
| +#include "content/public/common/renderer_preferences.h" |
| +#include "grit/browser_resources.h" |
| +#include "grit/chromium_strings.h" |
| +#include "grit/generated_resources.h" |
| +#include "ui/base/keycodes/keyboard_codes.h" |
| +#include "ui/base/l10n/l10n_util.h" |
| +#include "ui/base/resource/resource_bundle.h" |
| + |
| +#if defined(TOOLKIT_VIEWS) |
| +#include "ui/views/widget/widget.h" |
| +#endif |
| + |
| +using WebKit::WebDragOperation; |
| +using WebKit::WebDragOperationsMask; |
| +using content::OpenURLParams; |
| +using content::RenderViewHost; |
| +using content::WebContents; |
| + |
| +////////////////// |
| +// PlatformAppHost |
| + |
| +// TODO(benwells): SiteInstance should be created per platform app, not per |
| +// platform app host (which means per shell window). This probably means we |
| +// need some sort of PlatformAppSiteManager or something :( |
| +PlatformAppHost::PlatformAppHost(Profile* profile, |
| + const GURL& url) |
| + : profile_(profile), |
| + render_view_host_(NULL), |
| + did_stop_loading_(false), |
| + initial_url_(url), |
| + ALLOW_THIS_IN_INITIALIZER_LIST( |
| + extension_function_dispatcher_(profile_, this)), |
| + associated_web_contents_(NULL), |
|
Aaron Boodman
2012/04/20 07:05:53
This is always NULL and can be removed, which mean
benwells
2012/04/24 08:35:32
Done.
|
| + site_instance_(content::SiteInstance::Create(profile)) { |
| + host_contents_.reset(WebContents::Create( |
| + profile_, site_instance_.get(), MSG_ROUTING_NONE, NULL, NULL)); |
| + content::WebContentsObserver::Observe(host_contents_.get()); |
| + host_contents_->SetDelegate(this); |
| + host_contents_->SetViewType(chrome::VIEW_TYPE_APP_SHELL); |
| + host_contents_->GetMutableRendererPrefs()->browser_handles_all_requests = |
| + true; |
| + host_contents_->GetRenderViewHost()->SyncRendererPrefs(); |
| + |
| + prefs_tab_helper_.reset(new PrefsTabHelper(host_contents())); |
| + |
| + render_view_host_ = host_contents_->GetRenderViewHost(); |
|
Aaron Boodman
2012/04/20 07:05:53
Why do you need to store the rvh pointer?
benwells
2012/04/24 08:35:32
Gone.
|
| + |
| + CreateRenderViewSoon(); |
| +} |
| + |
| +PlatformAppHost::~PlatformAppHost() {} |
| + |
| +WebContents* PlatformAppHost::GetAssociatedWebContents() const { |
| + return associated_web_contents_; |
| +} |
| + |
| +void PlatformAppHost::SetAssociatedWebContents( |
| + content::WebContents* web_contents) { |
| + associated_web_contents_ = web_contents; |
| + if (web_contents) { |
| + registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
| + content::Source<WebContents>(associated_web_contents_)); |
| + } |
| +} |
| + |
| +content::RenderProcessHost* PlatformAppHost::render_process_host() const { |
| + return render_view_host()->GetProcess(); |
| +} |
| + |
| +void PlatformAppHost::CreateRenderViewSoon() { |
|
benwells
2012/04/19 09:03:55
This can move into constructor.
|
| + host_contents_->GetController().LoadURL( |
| + initial_url_, content::Referrer(), content::PAGE_TRANSITION_LINK, |
| + std::string()); |
| +} |
| + |
| +Browser* PlatformAppHost::GetBrowser() { |
| + return NULL; |
| +} |
| + |
| +void PlatformAppHost::Close() { |
| + // TODO(benwells):create NOTIFICATION_PLATFORM_APP_VIEW_SHOULD_CLOSE. |
| + // content::NotificationService::current()->Notify( |
| + // chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, |
| + // content::Source<Profile>(profile_), |
| + // content::Details<PlatformAppHost>(this)); |
| +} |
| + |
| +void PlatformAppHost::Observe(int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) { |
| + switch (type) { |
| + case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: |
| + if (content::Source<WebContents>(source).ptr() == |
| + associated_web_contents_) { |
| + associated_web_contents_ = NULL; |
| + } |
| + break; |
| + default: |
| + NOTREACHED() << "Unexpected notification sent."; |
| + break; |
| + } |
| +} |
| + |
| +void PlatformAppHost::DidStopLoading() { |
| + bool notify = !did_stop_loading_; |
| + did_stop_loading_ = true; |
| +#if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX) |
| + if (view_.get()) |
| + view_->DidStopLoading(); |
|
benwells
2012/04/19 09:03:55
I think this means I need to bring some sort of vi
Aaron Boodman
2012/04/20 07:05:53
ShellWindow is essentially that object. So that's
|
| +#endif |
| + if (notify) |
| + UMA_HISTOGRAM_TIMES("Extensions.ShellLoadTime", since_created_.Elapsed()); |
| +} |
| + |
| +void PlatformAppHost::CloseContents(WebContents* contents) { |
| + Close(); |
| +} |
| + |
| +bool PlatformAppHost::ShouldSuppressDialogs() { |
| + return true; |
| +} |
| + |
| +bool PlatformAppHost::OnMessageReceived(const IPC::Message& message) { |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(PlatformAppHost, message) |
| + IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + return handled; |
| +} |
| + |
| +void PlatformAppHost::OnRequest(const ExtensionHostMsg_Request_Params& params) { |
| + extension_function_dispatcher_.Dispatch(params, render_view_host()); |
| +} |
| + |
| +void PlatformAppHost::RenderViewDeleted(RenderViewHost* render_view_host) { |
|
Aaron Boodman
2012/04/20 07:05:53
Don't think this is needed?
benwells
2012/04/24 08:35:32
Done.
|
| + // If our RenderViewHost is deleted, fall back to the host_contents' current |
| + // RVH. There is sometimes a small gap between the pending RVH being deleted |
| + // and RenderViewCreated being called, so we update it here. |
| + if (render_view_host == render_view_host_) |
| + render_view_host_ = host_contents_->GetRenderViewHost(); |
| +} |