Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: src/plugin/PluginTabBase.cpp

Issue 29323611: Issue #1234, #2058 - Rewrite log facility, improving thread implementation
Left Patch Set: rebase only Created Nov. 26, 2015, 1:07 p.m.
Right Patch Set: rebase only Created July 27, 2016, 9:11 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/plugin/PluginTabBase.h ('k') | test/plugin/ActiveQueueTest.cpp » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH 3 * Copyright (C) 2006-2016 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #include "PluginStdAfx.h" 18 #include "PluginStdAfx.h"
19 #include "AdblockPlusClient.h" 19 #include "AdblockPlusClient.h"
20 #include "PluginSettings.h" 20 #include "PluginSettings.h"
21 #include "AdblockPlusDomTraverser.h" 21 #include "AdblockPlusDomTraverser.h"
22 #include "PluginTabBase.h" 22 #include "PluginTabBase.h"
23 #include "IeVersion.h" 23 #include "IeVersion.h"
24 #include "../shared/Utils.h"
24 #include <Mshtmhst.h> 25 #include <Mshtmhst.h>
25 26
26 CPluginTabBase::CPluginTabBase(CPluginClass* plugin) 27 CPluginTab::CPluginTab()
27 : m_plugin(plugin) 28 {
28 { 29 m_filter.hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL);
29 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter());
30 m_filter->hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL);
31 30
32 CPluginClient* client = CPluginClient::GetInstance(); 31 CPluginClient* client = CPluginClient::GetInstance();
33 m_traverser = new CPluginDomTraverser(static_cast<CPluginTab*>(this)); 32 m_traverser = new CPluginDomTraverser(static_cast<CPluginTab*>(this));
34 } 33 }
35 34
36 35 CPluginTab::~CPluginTab()
37 CPluginTabBase::~CPluginTabBase()
38 { 36 {
39 delete m_traverser; 37 delete m_traverser;
40 m_traverser = NULL; 38 m_traverser = NULL;
39 /**
40 * ABP only intercepts protocols "http:" and "https:".
41 * We can disable any domain used in those protocol with an appropriate whitelis t filter.
42 * Thus, the possibility to disable on a particular site depends only on the pro tocol.
43 */
44 bool CPluginTab::IsPossibleToDisableOnSite()
45 {
46 auto url = GetDocumentUrl();
47 return BeginsWith(url, L"http:") || BeginsWith(url, L"https:");
48 }
49
41 } 50 }
42 51
43 namespace 52 namespace
44 { 53 {
45 // Entry Point 54 // Entry Point
46 void FilterLoader(CPluginTabBase* tabBase) 55 void FilterLoader(CPluginFilter* filter, const std::wstring& domain)
47 { 56 {
48 try 57 try
49 { 58 {
50 tabBase->m_filter->LoadHideFilters(CPluginClient::GetInstance()->GetElemen tHidingSelectors(tabBase->GetDocumentDomain())); 59 filter->LoadHideFilters(CPluginClient::GetInstance()->GetElementHidingSele ctors(domain));
51 SetEvent(tabBase->m_filter->hideFiltersLoadedEvent); 60 SetEvent(filter->hideFiltersLoadedEvent);
52 } 61 }
53 catch (...) 62 catch (...)
54 { 63 {
55 // As a thread-main function, we truncate any C++ exception. 64 // As a thread-main function, we truncate any C++ exception.
56 } 65 }
57 } 66 }
58 } 67 }
59 68
60 void CPluginTabBase::OnNavigate(const std::wstring& url) 69 void CPluginTab::OnNavigate(const std::wstring& url)
61 { 70 {
62 SetDocumentUrl(url); 71 SetDocumentUrl(url);
63 ClearFrameCache(GetDocumentDomain()); 72 ClearFrameCache(GetDocumentDomain());
64 std::wstring domainString = GetDocumentDomain(); 73 std::wstring domainString = GetDocumentDomain();
65 ResetEvent(m_filter->hideFiltersLoadedEvent); 74 ResetEvent(m_filter.hideFiltersLoadedEvent);
66 try 75 try
67 { 76 {
68 std::thread filterLoaderThread(&FilterLoader, this); 77 std::thread filterLoaderThread(&FilterLoader, &m_filter, GetDocumentDomain() );
69 filterLoaderThread.detach(); // TODO: but actually we should wait for the th read in the dtr. 78 filterLoaderThread.detach(); // TODO: but actually we should wait for the th read in the dtr.
70 } 79 }
71 catch (const std::system_error& ex) 80 catch (const std::system_error& ex)
72 { 81 {
73 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CRE ATE_PROCESS, 82 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CRE ATE_PROCESS,
74 "Class::Thread - Failed to start filter loader thread"); 83 "Class::Thread - Failed to start filter loader thread");
75 } 84 }
76 m_traverser->ClearCache(); 85 m_traverser->ClearCache();
77 } 86 }
78 87
(...skipping 28 matching lines...) Expand all
107 return false; 116 return false;
108 } 117 }
109 auto urlCstr = url.c_str(); 118 auto urlCstr = url.c_str();
110 // Check the prefix to match our directory 119 // Check the prefix to match our directory
111 // Check the suffix to be an HTML file 120 // Check the suffix to be an HTML file
112 return (_wcsnicmp(urlCstr, dir.c_str(), dir.length()) == 0) && 121 return (_wcsnicmp(urlCstr, dir.c_str(), dir.length()) == 0) &&
113 (_wcsnicmp(urlCstr + url.length() - 5, L".html", 5) == 0); 122 (_wcsnicmp(urlCstr + url.length() - 5, L".html", 5) == 0);
114 } 123 }
115 } 124 }
116 125
117 void CPluginTabBase::InjectABP(IWebBrowser2* browser) 126 void CPluginTab::InjectABP(IWebBrowser2* browser)
118 { 127 {
119 CriticalSection::Lock lock(m_csInject); 128 CriticalSection::Lock lock(m_csInject);
120 auto url = GetDocumentUrl(); 129 auto url = GetDocumentUrl();
121 if (!IsOurHtmlFile(url)) 130 if (!IsOurHtmlFile(url))
122 { 131 {
123 DEBUG_GENERAL(L"InjectABP. Not injecting"); 132 DEBUG_GENERAL(L"InjectABP. Not injecting");
124 return; 133 return;
125 } 134 }
126 DEBUG_GENERAL(L"InjectABP. Injecting"); 135 DEBUG_GENERAL(L"InjectABP. Injecting");
127 CComPtr<IDispatch> pDocDispatch; 136 CComPtr<IDispatch> pDocDispatch;
128 browser->get_Document(&pDocDispatch); 137 browser->get_Document(&pDocDispatch);
129 CComQIPtr<IHTMLDocument2> pDoc2 = pDocDispatch; 138 CComQIPtr<IHTMLDocument2> pDoc2(pDocDispatch);
130 if (!pDoc2) 139 if (!pDoc2)
131 { 140 {
132 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI docume nt"); 141 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to QI document") ;
133 return; 142 return;
134 } 143 }
135 CComPtr<IHTMLWindow2> pWnd2; 144 CComPtr<IHTMLWindow2> pWnd2;
136 pDoc2->get_parentWindow(&pWnd2); 145 pDoc2->get_parentWindow(&pWnd2);
137 if (!pWnd2) 146 if (!pWnd2)
138 { 147 {
139 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get paren t window"); 148 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to get parent wi ndow");
140 return; 149 return;
141 } 150 }
142 CComQIPtr<IDispatchEx> pWndEx = pWnd2; 151 CComQIPtr<IDispatchEx> pWndEx(pWnd2);
143 if (!pWndEx) 152 if (!pWndEx)
144 { 153 {
145 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI dispat ch"); 154 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to QI dispatch") ;
146 return; 155 return;
147 } 156 }
148 // Create "Settings" object in JavaScript. 157 // Create "Settings" object in JavaScript.
149 // A method call of "Settings" in JavaScript, transfered to "Invoke" of m_plug inUserSettings 158 // A method call of "Settings" in JavaScript, transfered to "Invoke" of m_plug inUserSettings
150 DISPID dispid; 159 DISPID dispid;
151 HRESULT hr = pWndEx->GetDispID(L"Settings", fdexNameEnsure, &dispid); 160 HRESULT hr = pWndEx->GetDispID(L"Settings", fdexNameEnsure, &dispid);
152 if (FAILED(hr)) 161 if (FAILED(hr))
153 { 162 {
154 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CR EATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get disp atch"); 163 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CR EATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to get dispatch ");
155 return; 164 return;
156 } 165 }
157 CComVariant var((IDispatch*)&m_pluginUserSettings); 166 CComVariant var((IDispatch*)&m_pluginUserSettings);
158 167
159 DEBUG_GENERAL("Injecting"); 168 DEBUG_GENERAL("Injecting");
160 169
161 DISPPARAMS params; 170 DISPPARAMS params;
162 params.cArgs = 1; 171 params.cArgs = 1;
163 params.cNamedArgs = 0; 172 params.cNamedArgs = 0;
164 params.rgvarg = &var; 173 params.rgvarg = &var;
165 params.rgdispidNamedArgs = 0; 174 params.rgdispidNamedArgs = 0;
166 hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU T | DISPATCH_PROPERTYPUTREF, &params, 0, 0, 0); 175 hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU T | DISPATCH_PROPERTYPUTREF, &params, 0, 0, 0);
167 DEBUG_GENERAL("Invoke"); 176 DEBUG_GENERAL("Invoke");
168 if (FAILED(hr)) 177 if (FAILED(hr))
169 { 178 {
170 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CR EATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to create S ettings in JavaScript"); 179 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CR EATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to create Setti ngs in JavaScript");
171 } 180 }
172 } 181 }
173 182
174 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) 183 namespace
184 {
185 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser)
186 {
187 ATL::CComPtr<IDispatch> parentDispatch;
188 if (FAILED(browser.get_Parent(&parentDispatch)) || !parentDispatch)
189 {
190 return nullptr;
191 }
192 // The InternetExplorer application always returns a pointer to itself.
193 // https://msdn.microsoft.com/en-us/library/aa752136(v=vs.85).aspx
194 if (parentDispatch.IsEqualObject(&browser))
195 {
196 return nullptr;
197 }
198 ATL::CComQIPtr<IServiceProvider> parentDocumentServiceProvider = parentDispa tch;
199 if (!parentDocumentServiceProvider)
200 {
201 return nullptr;
202 }
203 ATL::CComPtr<IWebBrowser2> parentBrowser;
204 if (FAILED(parentDocumentServiceProvider->QueryService(SID_SWebBrowserApp, & parentBrowser)))
205 {
206 return nullptr;
207 }
208 return parentBrowser;
209 }
210
211 bool IsFrameWhiteListed(ATL::CComPtr<IWebBrowser2> frame)
212 {
213 if (!frame)
214 {
215 return false;
216 }
217 auto url = GetLocationUrl(*frame);
218 std::vector<std::string> frameHierarchy;
219 while(frame = GetParent(*frame))
220 {
221 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame)));
222 }
223 CPluginClient* client = CPluginClient::GetInstance();
224 return client->IsWhitelistedUrl(url, frameHierarchy)
225 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy);
226 }
227 }
228
229 void CPluginTab::OnDownloadComplete(IWebBrowser2* browser)
175 { 230 {
176 CPluginClient* client = CPluginClient::GetInstance(); 231 CPluginClient* client = CPluginClient::GetInstance();
177 std::wstring url = GetDocumentUrl(); 232 std::wstring url = GetDocumentUrl();
178 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(u rl)) 233 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(u rl))
179 { 234 {
180 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl() ); 235 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl() );
181 } 236 }
182 InjectABP(browser); 237 InjectABP(browser);
183 } 238 }
184 239
185 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin g& url, bool isDocumentBrowser) 240 void CPluginTab::OnDocumentComplete(IWebBrowser2* browser, const std::wstring& u rl, bool isDocumentBrowser)
186 { 241 {
187 std::wstring documentUrl = GetDocumentUrl(); 242 std::wstring documentUrl = GetDocumentUrl();
188 243
189 if (isDocumentBrowser) 244 if (isDocumentBrowser)
190 { 245 {
191 if (url != documentUrl) 246 if (url != documentUrl)
192 { 247 {
193 SetDocumentUrl(url); 248 SetDocumentUrl(url);
194 } 249 }
195 InjectABP(browser); 250 InjectABP(browser);
196 } 251 }
197 CString urlLegacy = ToCString(url); 252 if (BeginsWith(url, L"res://"))
198 if (urlLegacy.Left(6) != "res://") 253 {
199 { 254 return;
200 // Get document 255 }
201 CComPtr<IDispatch> pDocDispatch; 256 // Get document
202 HRESULT hr = browser->get_Document(&pDocDispatch); 257 CComPtr<IDispatch> pDocDispatch;
203 if (FAILED(hr) || !pDocDispatch) 258 HRESULT hr = browser->get_Document(&pDocDispatch);
204 { 259 if (FAILED(hr) || !pDocDispatch)
205 return; 260 {
206 } 261 return;
207 262 }
208 CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch; 263
209 if (!pDoc) 264 CComQIPtr<IHTMLDocument2> pDoc(pDocDispatch);
210 { 265 if (!pDoc)
211 return; 266 {
212 } 267 return;
213 CComPtr<IOleObject> pOleObj; 268 }
214 269
215 pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj); 270 CComPtr<IOleObject> pOleObj;
216 271 pDocDispatch->QueryInterface(&pOleObj);
217 272 if (!pOleObj)
218 CComPtr<IOleClientSite> pClientSite; 273 {
219 pOleObj->GetClientSite(&pClientSite); 274 return;
220 if (pClientSite != NULL) 275 }
221 { 276 CComPtr<IOleClientSite> pClientSite;
222 CComPtr<IDocHostUIHandler> docHostUIHandler; 277 pOleObj->GetClientSite(&pClientSite);
223 pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandl er); 278 if (pClientSite != NULL)
224 if (docHostUIHandler != NULL) 279 {
225 { 280 CComPtr<IDocHostUIHandler> docHostUIHandler;
226 docHostUIHandler->UpdateUI(); 281 pClientSite->QueryInterface(&docHostUIHandler);
227 } 282 if (docHostUIHandler != NULL)
228 } 283 {
229 } 284 docHostUIHandler->UpdateUI();
230 } 285 }
231 286 }
232 std::wstring CPluginTabBase::GetDocumentDomain() 287 }
288
289 std::wstring CPluginTab::GetDocumentDomain()
233 { 290 {
234 std::wstring domain; 291 std::wstring domain;
235 292
236 m_criticalSection.Lock(); 293 m_criticalSection.Lock();
237 { 294 {
238 domain = m_documentDomain; 295 domain = m_documentDomain;
239 } 296 }
240 m_criticalSection.Unlock(); 297 m_criticalSection.Unlock();
241 298
242 return domain; 299 return domain;
243 } 300 }
244 301
245 void CPluginTabBase::SetDocumentUrl(const std::wstring& url) 302 void CPluginTab::SetDocumentUrl(const std::wstring& url)
246 { 303 {
247 m_criticalSection.Lock(); 304 m_criticalSection.Lock();
248 { 305 {
249 m_documentUrl = url; 306 m_documentUrl = url;
250 m_documentDomain = CAdblockPlusClient::GetInstance()->GetHostFromUrl(url); 307 m_documentDomain = CAdblockPlusClient::GetInstance()->GetHostFromUrl(url);
251 } 308 }
252 m_criticalSection.Unlock(); 309 m_criticalSection.Unlock();
253 } 310 }
254 311
255 std::wstring CPluginTabBase::GetDocumentUrl() 312 std::wstring CPluginTab::GetDocumentUrl()
256 { 313 {
257 std::wstring url; 314 std::wstring url;
258 315
259 m_criticalSection.Lock(); 316 m_criticalSection.Lock();
260 { 317 {
261 url = m_documentUrl; 318 url = m_documentUrl;
262 } 319 }
263 m_criticalSection.Unlock(); 320 m_criticalSection.Unlock();
264 321
265 return url; 322 return url;
266 } 323 }
267 324
268 325
269 // ============================================================================ 326 // ============================================================================
270 // Frame caching 327 // Frame caching
271 // ============================================================================ 328 // ============================================================================
272 bool CPluginTabBase::IsFrameCached(const std::wstring& url) 329 bool CPluginTab::IsFrameCached(const std::wstring& url)
273 { 330 {
274 bool isFrame; 331 bool isFrame;
275 332
276 m_criticalSectionCache.Lock(); 333 m_criticalSectionCache.Lock();
277 { 334 {
278 isFrame = m_cacheFrames.find(url) != m_cacheFrames.end(); 335 isFrame = m_cacheFrames.find(url) != m_cacheFrames.end();
279 } 336 }
280 m_criticalSectionCache.Unlock(); 337 m_criticalSectionCache.Unlock();
281 338
282 return isFrame; 339 return isFrame;
283 } 340 }
284 341
285 void CPluginTabBase::CacheFrame(const std::wstring& url) 342 void CPluginTab::CacheFrame(const std::wstring& url)
286 { 343 {
287 m_criticalSectionCache.Lock(); 344 m_criticalSectionCache.Lock();
288 { 345 {
289 m_cacheFrames.insert(url); 346 m_cacheFrames.insert(url);
290 } 347 }
291 m_criticalSectionCache.Unlock(); 348 m_criticalSectionCache.Unlock();
292 } 349 }
293 350
294 void CPluginTabBase::ClearFrameCache(const std::wstring& domain) 351 void CPluginTab::ClearFrameCache(const std::wstring& domain)
295 { 352 {
296 m_criticalSectionCache.Lock(); 353 m_criticalSectionCache.Lock();
297 { 354 {
298 if (domain.empty() || domain != m_cacheDomain) 355 if (domain.empty() || domain != m_cacheDomain)
299 { 356 {
300 m_cacheFrames.clear(); 357 m_cacheFrames.clear();
301 m_cacheDomain = domain; 358 m_cacheDomain = domain;
302 } 359 }
303 } 360 }
304 m_criticalSectionCache.Unlock(); 361 m_criticalSectionCache.Unlock();
305 } 362 }
306 363
LEFTRIGHT

Powered by Google App Engine
This is Rietveld