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 |