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

Side by Side Diff: src/engine/Main.cpp

Issue 6505394822184960: Issue 1109 - Support notifications (Closed)
Patch Set: add border and shadow and remove title background Created July 3, 2015, 1:37 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
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-2015 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 #pragma comment(linker,"\"/manifestdependency:type='win32' \
19 name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
20 processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
21
18 #include <AdblockPlus.h> 22 #include <AdblockPlus.h>
19 #include <functional> 23 #include <functional>
20 #include <vector> 24 #include <vector>
21 #include <thread> 25 #include <thread>
22 #include <Windows.h> 26 #include <Windows.h>
23 27
24 #include "../shared/AutoHandle.h" 28 #include "../shared/AutoHandle.h"
25 #include "../shared/Communication.h" 29 #include "../shared/Communication.h"
26 #include "../shared/Dictionary.h" 30 #include "../shared/Dictionary.h"
27 #include "../shared/Utils.h" 31 #include "../shared/Utils.h"
28 #include "../shared/Version.h" 32 #include "../shared/Version.h"
29 #include "../shared/CriticalSection.h" 33 #include "../shared/CriticalSection.h"
30 #include "IeVersion.h" 34 #include "IeVersion.h"
31 #include "AdblockPlus.h" 35 #include "AdblockPlus.h"
32 #include "Debug.h" 36 #include "Debug.h"
33 #include "Updater.h" 37 #include "Updater.h"
38 #include "NotificationWindow.h"
34 39
35 namespace 40 namespace
36 { 41 {
42 class MyModule : public ATL::CAtlExeModuleT<MyModule> {
43 public:
44 } _AtlModule;
45
37 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine; 46 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine;
38 std::auto_ptr<Updater> updater; 47 std::auto_ptr<Updater> updater;
39 int activeConnections = 0; 48 int activeConnections = 0;
40 CriticalSection activeConnectionsLock; 49 CriticalSection activeConnectionsLock;
41 HWND callbackWindow; 50 HWND callbackWindow;
42 51
43 void WriteSubscriptions(Communication::OutputBuffer& response, 52 void WriteSubscriptions(Communication::OutputBuffer& response,
44 const std::vector<AdblockPlus::SubscriptionPtr>& subscriptions) 53 const std::vector<AdblockPlus::SubscriptionPtr>& subscriptions)
45 { 54 {
46 int32_t count = static_cast<int32_t>(subscriptions.size()); 55 int32_t count = static_cast<int32_t>(subscriptions.size());
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 { 430 {
422 if (params.size() < 1) 431 if (params.size() < 1)
423 { 432 {
424 Debug("updateAvailable event missing URL"); 433 Debug("updateAvailable event missing URL");
425 return; 434 return;
426 } 435 }
427 updateAvailable = true; 436 updateAvailable = true;
428 437
429 updater->Update(params[0]->AsString()); 438 updater->Update(params[0]->AsString());
430 } 439 }
431 }
432 440
433 std::auto_ptr<AdblockPlus::FilterEngine> CreateFilterEngine(const std::wstring& locale) 441 std::auto_ptr<AdblockPlus::FilterEngine> CreateFilterEngine(const std::wstring& locale)
434 { 442 {
435 AdblockPlus::AppInfo appInfo; 443 AdblockPlus::AppInfo appInfo;
436 appInfo.version = ToUtf8String(IEPLUGIN_VERSION); 444 appInfo.version = ToUtf8String(IEPLUGIN_VERSION);
437 appInfo.name = "adblockplusie"; 445 appInfo.name = "adblockplusie";
438 #ifdef _WIN64 446 #ifdef _WIN64
439 appInfo.application = "msie64"; 447 appInfo.application = "msie64";
440 #else 448 #else
441 appInfo.application = "msie32"; 449 appInfo.application = "msie32";
442 #endif 450 #endif
443 appInfo.applicationVersion = ToUtf8String(AdblockPlus::IE::InstalledVersionStr ing()); 451 appInfo.applicationVersion = ToUtf8String(AdblockPlus::IE::InstalledVersionStr ing());
444 appInfo.locale = ToUtf8String(locale); 452 appInfo.locale = ToUtf8String(locale);
445 #ifdef ADBLOCK_PLUS_TEST_MODE 453 #ifdef ADBLOCK_PLUS_TEST_MODE
446 appInfo.developmentBuild = true; 454 appInfo.developmentBuild = true;
447 #else 455 #else
448 appInfo.developmentBuild = false; 456 appInfo.developmentBuild = false;
449 #endif 457 #endif
450 458
451 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::New(appInfo); 459 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::New(appInfo);
452 jsEngine->SetEventCallback("updateAvailable", &OnUpdateAvailable); 460 jsEngine->SetEventCallback("updateAvailable", &OnUpdateAvailable);
453 461
454 std::string dataPath = ToUtf8String(GetAppDataPath()); 462 std::string dataPath = ToUtf8String(GetAppDataPath());
455 dynamic_cast<AdblockPlus::DefaultFileSystem*>(jsEngine->GetFileSystem().get()) ->SetBasePath(dataPath); 463 dynamic_cast<AdblockPlus::DefaultFileSystem*>(jsEngine->GetFileSystem().get()) ->SetBasePath(dataPath);
456 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine(new AdblockPlus::FilterE ngine(jsEngine)); 464 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine(new AdblockPlus::FilterE ngine(jsEngine));
457 return filterEngine; 465 return filterEngine;
458 } 466 }
459 467
460 int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 468 class ScopedTimer
469 {
470 public:
471 explicit ScopedTimer(HWND hwnd, UINT_PTR timerId, UINT elapse, TIMERPROC timer Proc)
472 : m_hwnd(hwnd), m_timerId(timerId)
473 {
474 m_timerId = SetTimer(m_hwnd, m_timerId, elapse, timerProc);
475 }
476 ~ScopedTimer()
477 {
478 Close();
479 }
480
481 UINT_PTR GetID()
482 {
483 return m_timerId;
484 }
485
486 operator bool() const
487 {
488 return m_timerId != 0;
489 }
490
491 void Close()
492 {
493 if (m_timerId)
494 {
495 KillTimer(m_hwnd, m_timerId);
496 m_timerId = 0;
497 }
498 }
499 private:
500 ScopedTimer(const ScopedTimer&);
501 ScopedTimer& operator=(const ScopedTimer&);
502 private:
503 HWND m_hwnd;
504 UINT_PTR m_timerId;
505 };
506
507 struct ScopedAtlAxInitializer
508 {
509 ScopedAtlAxInitializer()
510 {
511 ATL::AtlAxWinInit();
512 }
513 ~ScopedAtlAxInitializer()
514 {
515 ATL::AtlAxWinTerm();
516 }
517 };
518
519 void ApplicationMessageLoop(HINSTANCE hInstance)
Oleksandr 2015/07/22 09:45:35 I still think using CreateTimerQueueTimer instead
sergei 2015/07/23 14:17:57 What is a window listener? Anyway the timer is rem
520 {
521 const std::wstring className = L"ABPEngineMessageWindow";
522 WNDCLASS wc;
523 wc.style = 0;
524 wc.lpfnWndProc = DefWindowProcW;
525 wc.cbClsExtra = 0;
526 wc.cbWndExtra = 0;
527 wc.hInstance = hInstance;
528 wc.hIcon = nullptr;
529 wc.hCursor = nullptr;
530 wc.hbrBackground = nullptr;
531 wc.lpszMenuName = nullptr;
532 wc.lpszClassName = className.c_str();
533 ATOM atom = RegisterClass(&wc);
534 if (!atom)
535 {
536 DebugLastError("Cannot register class for message only window");
537 return;
538 }
539 HWND msgHWnd = CreateWindowW(className.c_str(),
540 nullptr, // window name
541 0, // style
542 0, 0, 0, 0, // geometry (x, y, w, h)
543 HWND_MESSAGE, // parent
544 nullptr, // menu handle
545 hInstance,
546 0); // windows creation data.
547 if (!msgHWnd)
548 {
549 DebugLastError("Cannot create message only window");
550 return;
551 }
552 MSG msg = {};
553 ScopedTimer notificationTimer(msgHWnd, /*timer ID*/1, 3000/*msec*/, nullptr);
554 std::unique_ptr<NotificationBorderWindow> notificationWindow;
555 while (GetMessage(&msg, /*hwnd*/nullptr, /*msgFilterMin*/0, /*msgFilterMax*/0) )
556 {
557 if (msg.hwnd == msgHWnd)
558 {
559 if (msg.message == WM_TIMER)
560 {
561 if (msg.wParam == notificationTimer.GetID())
562 {
563 notificationTimer.Close();
564 auto notification = filterEngine->GetNextNotificationToShow();
565 if (notification)
566 {
567 notificationWindow.reset(new NotificationBorderWindow(*notification, GetExeDir() + L"html\\templates\\"));
568 notificationWindow->SetOnDestroyed([&notificationWindow]
569 {
570 notificationWindow.reset();
571 });
572 notificationWindow->SetOnLinkClicked([](const std::wstring& url)
573 {
574 ATL::CComPtr<IWebBrowser2> webBrowser;
575 if (SUCCEEDED(webBrowser.CoCreateInstance(__uuidof(InternetExplore r))) && webBrowser)
576 {
577 ATL::CComVariant emptyVariant;
578 webBrowser->Navigate(ATL::CComBSTR(url.c_str()), &emptyVariant, &emptyVariant, &emptyVariant, &emptyVariant);
579 webBrowser->put_Visible(VARIANT_TRUE);
580 }
581 });
582 notificationWindow->Create(/*parent window*/nullptr);
583 if (notificationWindow->operator HWND() != nullptr)
584 {
585 notificationWindow->ShowWindow(SW_SHOWNOACTIVATE);
586 notificationWindow->UpdateWindow();
587 }
588 }
589 }
590 }
591 }
592 TranslateMessage(&msg);
593 DispatchMessage(&msg);
594 }
595 }
596
597 } // namespace {
598
599 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
461 { 600 {
462 AutoHandle mutex(CreateMutexW(0, false, L"AdblockPlusEngine")); 601 AutoHandle mutex(CreateMutexW(0, false, L"AdblockPlusEngine"));
463 if (!mutex) 602 if (!mutex)
464 { 603 {
465 DebugLastError("CreateMutex failed"); 604 DebugLastError("CreateMutex failed");
466 return 1; 605 return 1;
467 } 606 }
468 607
469 if (GetLastError() == ERROR_ALREADY_EXISTS) 608 if (GetLastError() == ERROR_ALREADY_EXISTS)
470 { 609 {
471 DebugLastError("Named pipe exists, another engine instance appears to be run ning"); 610 DebugLastError("Named pipe exists, another engine instance appears to be run ning");
472 return 1; 611 return 1;
473 } 612 }
474 613
475 int argc; 614 int argc;
476 LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); 615 LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
477 std::wstring locale(argc >= 2 ? argv[1] : L""); 616 std::wstring locale(argc >= 2 ? argv[1] : L"");
478 LocalFree(argv); 617 LocalFree(argv);
479 Dictionary::Create(locale); 618 Dictionary::Create(locale);
480 filterEngine = CreateFilterEngine(locale); 619 filterEngine = CreateFilterEngine(locale);
481 updater.reset(new Updater(filterEngine->GetJsEngine())); 620 updater.reset(new Updater(filterEngine->GetJsEngine()));
482 621
483 for (;;) 622 std::thread communicationThread([]
484 { 623 {
485 try 624 for (;;)
486 { 625 {
487 auto pipe = std::make_shared<Communication::Pipe>(Communication::pipeName, Communication::Pipe::MODE_CREATE); 626 try
627 {
628 auto pipe = std::make_shared<Communication::Pipe>(Communication::pipeNam e, Communication::Pipe::MODE_CREATE);
629
630 // TODO: we should wait for the finishing of the thread before exiting f rom this function.
631 // It works now in most cases because the browser waits for the response in the pipe, and the
632 // thread has time to finish while this response is being processed and the browser is
633 // disposing all its stuff.
634 std::thread([pipe]()
635 {
636 ClientThread(pipe.get());
637 }).detach();
638 }
639 catch(const std::system_error& ex)
640 {
641 DebugException(ex);
642 return 1;
643 }
644 catch (const std::runtime_error& e)
645 {
646 DebugException(e);
647 return 1;
648 }
649 }
650 });
488 651
489 // TODO: we should wait for the finishing of the thread before exiting fro m this function. 652 ScopedAtlAxInitializer atlAxInit;
490 // It works now in most cases because the browser waits for the response i n the pipe, and the 653 ApplicationMessageLoop(hInstance);
491 // thread has time to finish while this response is being processed and th e browser is 654 if (communicationThread.joinable())
492 // disposing all its stuff. 655 {
493 std::thread([pipe]() 656 communicationThread.join();
494 {
495 ClientThread(pipe.get());
496 }).detach();
497 }
498 catch(const std::system_error& ex)
499 {
500 DebugException(ex);
501 return 1;
502 }
503 catch (const std::runtime_error& e)
504 {
505 DebugException(e);
506 return 1;
507 }
508 } 657 }
509 658
659
Oleksandr 2015/07/22 09:45:35 NIT: Extra line here
sergei 2015/07/23 14:17:57 Fixed
510 return 0; 660 return 0;
511 } 661 }
OLDNEW

Powered by Google App Engine
This is Rietveld