| 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 // Implementation of ChromeActiveDocument | 5 // Implementation of ChromeActiveDocument |
| 6 #include "chrome_frame/chrome_active_document.h" | 6 #include "chrome_frame/chrome_active_document.h" |
| 7 | 7 |
| 8 #include <hlink.h> | 8 #include <hlink.h> |
| 9 #include <htiface.h> | 9 #include <htiface.h> |
| 10 #include <initguid.h> | 10 #include <initguid.h> |
| 11 #include <mshtmcid.h> | 11 #include <mshtmcid.h> |
| 12 #include <shdeprecated.h> | 12 #include <shdeprecated.h> |
| 13 #include <shlguid.h> | 13 #include <shlguid.h> |
| 14 #include <shlobj.h> | 14 #include <shlobj.h> |
| 15 #include <shobjidl.h> | 15 #include <shobjidl.h> |
| 16 #include <tlogstg.h> | 16 #include <tlogstg.h> |
| 17 #include <urlmon.h> | 17 #include <urlmon.h> |
| 18 #include <wininet.h> | 18 #include <wininet.h> |
| 19 | 19 |
| 20 #include "base/command_line.h" | 20 #include "base/command_line.h" |
| 21 #include "base/debug/trace_event.h" | 21 #include "base/debug/trace_event.h" |
| 22 #include "base/file_util.h" | |
| 23 #include "base/logging.h" | 22 #include "base/logging.h" |
| 24 #include "base/path_service.h" | |
| 25 #include "base/process_util.h" | |
| 26 #include "base/string_tokenizer.h" | |
| 27 #include "base/string_util.h" | 23 #include "base/string_util.h" |
| 28 #include "base/threading/thread.h" | |
| 29 #include "base/threading/thread_local.h" | |
| 30 #include "base/utf_string_conversions.h" | 24 #include "base/utf_string_conversions.h" |
| 31 #include "base/win/scoped_variant.h" | 25 #include "base/win/scoped_variant.h" |
| 32 #include "base/win/win_util.h" | |
| 33 #include "chrome/app/chrome_command_ids.h" | 26 #include "chrome/app/chrome_command_ids.h" |
| 34 #include "chrome/app/chrome_dll_resource.h" | 27 #include "chrome/app/chrome_dll_resource.h" |
| 35 #include "chrome/common/automation_messages.h" | 28 #include "chrome/common/automation_messages.h" |
| 36 #include "chrome/common/chrome_constants.h" | 29 #include "chrome/common/chrome_constants.h" |
| 37 #include "chrome/test/automation/browser_proxy.h" | 30 #include "chrome/test/automation/browser_proxy.h" |
| 38 #include "chrome/test/automation/tab_proxy.h" | 31 #include "chrome/test/automation/tab_proxy.h" |
| 39 #include "chrome_frame/bho.h" | 32 #include "chrome_frame/bho.h" |
| 40 #include "chrome_frame/bind_context_info.h" | 33 #include "chrome_frame/bind_context_info.h" |
| 41 #include "chrome_frame/buggy_bho_handling.h" | 34 #include "chrome_frame/buggy_bho_handling.h" |
| 42 #include "chrome_frame/crash_reporting/crash_metrics.h" | 35 #include "chrome_frame/crash_reporting/crash_metrics.h" |
| 43 #include "chrome_frame/utils.h" | 36 #include "chrome_frame/utils.h" |
| 44 #include "content/browser/tab_contents/tab_contents.h" | 37 #include "content/browser/tab_contents/tab_contents.h" |
| 45 #include "content/common/navigation_types.h" | 38 #include "content/common/navigation_types.h" |
| 46 #include "content/common/page_zoom.h" | 39 #include "content/common/page_zoom.h" |
| 47 #include "grit/generated_resources.h" | 40 #include "grit/generated_resources.h" |
| 48 | 41 |
| 49 DEFINE_GUID(CGID_DocHostCmdPriv, 0x000214D4L, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, | 42 DEFINE_GUID(CGID_DocHostCmdPriv, 0x000214D4L, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, |
| 50 0x46); | 43 0x46); |
| 51 | 44 |
| 52 base::ThreadLocalPointer<ChromeActiveDocument> g_active_doc_cache; | |
| 53 | |
| 54 bool g_first_launch_by_process_ = true; | 45 bool g_first_launch_by_process_ = true; |
| 55 | 46 |
| 56 const DWORD kIEEncodingIdArray[] = { | 47 const DWORD kIEEncodingIdArray[] = { |
| 57 #define DEFINE_ENCODING_ID_ARRAY(encoding_name, id, chrome_name) encoding_name, | 48 #define DEFINE_ENCODING_ID_ARRAY(encoding_name, id, chrome_name) encoding_name, |
| 58 INTERNAL_IE_ENCODINGMENU_IDS(DEFINE_ENCODING_ID_ARRAY) | 49 INTERNAL_IE_ENCODINGMENU_IDS(DEFINE_ENCODING_ID_ARRAY) |
| 59 #undef DEFINE_ENCODING_ID_ARRAY | 50 #undef DEFINE_ENCODING_ID_ARRAY |
| 60 0 // The Last data must be 0 to indicate the end of the encoding id array. | 51 0 // The Last data must be 0 to indicate the end of the encoding id array. |
| 61 }; | 52 }; |
| 62 | 53 |
| 63 ChromeActiveDocument::ChromeActiveDocument() | 54 ChromeActiveDocument::ChromeActiveDocument() |
| 64 : navigation_info_(new NavigationInfo()), | 55 : navigation_info_(new NavigationInfo()), |
| 65 first_navigation_(true), | 56 first_navigation_(true), |
| 66 is_automation_client_reused_(false), | 57 is_automation_client_reused_(false), |
| 67 popup_allowed_(false), | 58 popup_allowed_(false), |
| 68 accelerator_table_(NULL) { | 59 accelerator_table_(NULL) { |
| 69 TRACE_EVENT_BEGIN_ETW("chromeframe.createactivedocument", this, ""); | 60 TRACE_EVENT_BEGIN_ETW("chromeframe.createactivedocument", this, ""); |
| 70 | 61 |
| 71 url_fetcher_->set_frame_busting(false); | 62 url_fetcher_->set_frame_busting(false); |
| 72 memset(navigation_info_.get(), 0, sizeof(NavigationInfo)); | 63 memset(navigation_info_.get(), 0, sizeof(NavigationInfo)); |
| 73 } | 64 } |
| 74 | 65 |
| 75 HRESULT ChromeActiveDocument::FinalConstruct() { | 66 HRESULT ChromeActiveDocument::FinalConstruct() { |
| 76 // If we have a cached ChromeActiveDocument instance in TLS, then grab | 67 // The FinalConstruct implementation in the ChromeFrameActivexBase class |
| 77 // ownership of the cached document's automation client. This is an | 68 // i.e. Base creates an instance of the ChromeFrameAutomationClient class |
| 78 // optimization to get Chrome active documents to load faster. | 69 // and initializes it, which would spawn a new Chrome process, etc. |
| 79 ChromeActiveDocument* cached_document = g_active_doc_cache.Get(); | 70 // We don't want to be doing this if we have a cached document, whose |
| 80 if (cached_document && cached_document->IsValid()) { | 71 // automation client instance can be reused. |
| 81 SetResourceModule(); | 72 HRESULT hr = BaseActiveX::FinalConstruct(); |
| 82 DCHECK(automation_client_.get() == NULL); | 73 if (FAILED(hr)) |
| 83 automation_client_.swap(cached_document->automation_client_); | 74 return hr; |
| 84 DVLOG(1) << "Reusing automation client instance from " << cached_document; | |
| 85 DCHECK(automation_client_.get() != NULL); | |
| 86 automation_client_->Reinitialize(this, url_fetcher_.get()); | |
| 87 is_automation_client_reused_ = true; | |
| 88 OnAutomationServerReady(); | |
| 89 } else { | |
| 90 // The FinalConstruct implementation in the ChromeFrameActivexBase class | |
| 91 // i.e. Base creates an instance of the ChromeFrameAutomationClient class | |
| 92 // and initializes it, which would spawn a new Chrome process, etc. | |
| 93 // We don't want to be doing this if we have a cached document, whose | |
| 94 // automation client instance can be reused. | |
| 95 HRESULT hr = BaseActiveX::FinalConstruct(); | |
| 96 if (FAILED(hr)) | |
| 97 return hr; | |
| 98 } | |
| 99 | 75 |
| 100 InitializeAutomationSettings(); | 76 InitializeAutomationSettings(); |
| 101 | 77 |
| 102 find_dialog_.Init(automation_client_.get()); | 78 find_dialog_.Init(automation_client_.get()); |
| 103 | 79 |
| 104 OLECMDF flags = static_cast<OLECMDF>(OLECMDF_ENABLED | OLECMDF_SUPPORTED); | 80 OLECMDF flags = static_cast<OLECMDF>(OLECMDF_ENABLED | OLECMDF_SUPPORTED); |
| 105 | 81 |
| 106 null_group_commands_map_[OLECMDID_PRINT] = flags; | 82 null_group_commands_map_[OLECMDID_PRINT] = flags; |
| 107 null_group_commands_map_[OLECMDID_FIND] = flags; | 83 null_group_commands_map_[OLECMDID_FIND] = flags; |
| 108 null_group_commands_map_[OLECMDID_CUT] = flags; | 84 null_group_commands_map_[OLECMDID_CUT] = flags; |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 (*in_place_frame)->AddRef(); | 512 (*in_place_frame)->AddRef(); |
| 537 return S_OK; | 513 return S_OK; |
| 538 } else { | 514 } else { |
| 539 return S_FALSE; | 515 return S_FALSE; |
| 540 } | 516 } |
| 541 } | 517 } |
| 542 | 518 |
| 543 HRESULT ChromeActiveDocument::IOleObject_SetClientSite( | 519 HRESULT ChromeActiveDocument::IOleObject_SetClientSite( |
| 544 IOleClientSite* client_site) { | 520 IOleClientSite* client_site) { |
| 545 if (client_site == NULL) { | 521 if (client_site == NULL) { |
| 546 ChromeActiveDocument* cached_document = g_active_doc_cache.Get(); | |
| 547 if (cached_document) { | |
| 548 DCHECK(this == cached_document); | |
| 549 g_active_doc_cache.Set(NULL); | |
| 550 cached_document->Release(); | |
| 551 } | |
| 552 | |
| 553 base::win::ScopedComPtr<IDocHostUIHandler> doc_host_handler; | 522 base::win::ScopedComPtr<IDocHostUIHandler> doc_host_handler; |
| 554 if (doc_site_) | 523 if (doc_site_) |
| 555 doc_host_handler.QueryFrom(doc_site_); | 524 doc_host_handler.QueryFrom(doc_site_); |
| 556 | 525 |
| 557 if (doc_host_handler.get()) | 526 if (doc_host_handler.get()) |
| 558 doc_host_handler->HideUI(); | 527 doc_host_handler->HideUI(); |
| 559 | 528 |
| 560 doc_site_.Release(); | 529 doc_site_.Release(); |
| 561 } | 530 } |
| 562 | 531 |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 } | 936 } |
| 968 } | 937 } |
| 969 } | 938 } |
| 970 bool should_unload = true; | 939 bool should_unload = true; |
| 971 automation_client_->OnUnload(&should_unload); | 940 automation_client_->OnUnload(&should_unload); |
| 972 out_args->vt = VT_BOOL; | 941 out_args->vt = VT_BOOL; |
| 973 out_args->boolVal = should_unload ? VARIANT_TRUE : VARIANT_FALSE; | 942 out_args->boolVal = should_unload ? VARIANT_TRUE : VARIANT_FALSE; |
| 974 } | 943 } |
| 975 } | 944 } |
| 976 | 945 |
| 977 void ChromeActiveDocument::OnOpenURL(const GURL& url_to_open, | |
| 978 const GURL& referrer, | |
| 979 int open_disposition) { | |
| 980 // If the disposition indicates that we should be opening the URL in the | |
| 981 // current tab, then we can reuse the ChromeFrameAutomationClient instance | |
| 982 // maintained by the current ChromeActiveDocument instance. We cache this | |
| 983 // instance so that it can be used by the new ChromeActiveDocument instance | |
| 984 // which may be instantiated for handling the new URL. | |
| 985 if (open_disposition == CURRENT_TAB) { | |
| 986 // Grab a reference to ensure that the document remains valid. | |
| 987 AddRef(); | |
| 988 g_active_doc_cache.Set(this); | |
| 989 } | |
| 990 | |
| 991 BaseActiveX::OnOpenURL(url_to_open, referrer, open_disposition); | |
| 992 } | |
| 993 | |
| 994 void ChromeActiveDocument::OnAttachExternalTab( | 946 void ChromeActiveDocument::OnAttachExternalTab( |
| 995 const AttachExternalTabParams& params) { | 947 const AttachExternalTabParams& params) { |
| 996 if (!automation_client_.get()) { | 948 if (!automation_client_.get()) { |
| 997 DLOG(WARNING) << "Invalid automation client instance"; | 949 DLOG(WARNING) << "Invalid automation client instance"; |
| 998 return; | 950 return; |
| 999 } | 951 } |
| 1000 DWORD flags = 0; | 952 DWORD flags = 0; |
| 1001 if (params.user_gesture) | 953 if (params.user_gesture) |
| 1002 flags = NWMF_USERREQUESTED; | 954 flags = NWMF_USERREQUESTED; |
| 1003 else if (popup_allowed_) | 955 else if (popup_allowed_) |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1440 return true; | 1392 return true; |
| 1441 | 1393 |
| 1442 if (new_navigation_info.url != navigation_info_->url) | 1394 if (new_navigation_info.url != navigation_info_->url) |
| 1443 return true; | 1395 return true; |
| 1444 | 1396 |
| 1445 if (new_navigation_info.referrer != navigation_info_->referrer) | 1397 if (new_navigation_info.referrer != navigation_info_->referrer) |
| 1446 return true; | 1398 return true; |
| 1447 | 1399 |
| 1448 return false; | 1400 return false; |
| 1449 } | 1401 } |
| OLD | NEW |