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

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

Issue 11304082: Download updates automatically, ask to install from a modeless dialog (Closed)
Patch Set: Created July 31, 2013, 7:16 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 #include <functional> 1 #include <functional>
2 #include <memory> 2 #include <memory>
3 #include <sstream> 3 #include <sstream>
4 4
5 #include <Windows.h> 5 #include <Windows.h>
6 6
7 #include <AdblockPlus/FileSystem.h> 7 #include <AdblockPlus/FileSystem.h>
8 #include <AdblockPlus/WebRequest.h> 8 #include <AdblockPlus/WebRequest.h>
9 9
10 #include "../shared/AutoHandle.h" 10 #include "../shared/AutoHandle.h"
11 #include "../shared/Dictionary.h" 11 #include "../shared/Dictionary.h"
12 #include "../shared/Utils.h" 12 #include "../shared/Utils.h"
13 #include "Debug.h" 13 #include "Debug.h"
14 #include "Resource.h" 14 #include "Resource.h"
15 #include "UpdateInstallDialog.h"
15 #include "Updater.h" 16 #include "Updater.h"
16 17
17 namespace 18 namespace
18 { 19 {
19 typedef std::function<void()> ThreadCallbackType; 20 typedef std::function<void()> ThreadCallbackType;
20 typedef std::function<void(HWND)> DialogCallbackType;
21 21
22 const int DOWNLOAD_FAILED = 101; 22 const int DOWNLOAD_FAILED = 101;
23 23
24 LRESULT CALLBACK UpdateDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar am)
25 {
26 switch (msg)
27 {
28 case WM_INITDIALOG:
29 {
30 Dictionary* dict = Dictionary::GetInstance();
31 SetWindowTextW(hWnd, dict->Lookup("updater", "update-title").c_str());
32 SetDlgItemTextW(hWnd, IDC_UPDATETEXT, dict->Lookup("updater", "update-te xt").c_str());
33 SetDlgItemTextW(hWnd, IDC_DOYOU, dict->Lookup("updater", "update-questio n").c_str());
34 SetDlgItemTextW(hWnd, IDOK, dict->Lookup("general", "button-yes").c_str( ));
35 SetDlgItemTextW(hWnd, IDCANCEL, dict->Lookup("general", "button-no").c_s tr());
36 return TRUE;
37 }
38 case WM_COMMAND:
39 {
40 if (wParam == IDOK || wParam == IDCANCEL)
41 {
42 EndDialog(hWnd, wParam);
43 return TRUE;
44 }
45 break;
46 }
47 }
48
49 return FALSE;
50 }
51
52 LRESULT CALLBACK DownloadDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP aram)
53 {
54 // TODO: Indicate progress
55
56 switch (msg)
57 {
58 case WM_INITDIALOG:
59 {
60 Dictionary* dict = Dictionary::GetInstance();
61 SetWindowTextW(hWnd, dict->Lookup("updater", "download-title").c_str());
62 SetDlgItemTextW(hWnd, IDC_INSTALLMSG, dict->Lookup("updater", "download- progress-text").c_str());
63 SetDlgItemTextW(hWnd, IDCANCEL, dict->Lookup("general", "button-cancel") .c_str());
64
65 std::auto_ptr<DialogCallbackType> callback(reinterpret_cast<DialogCallba ckType*>(lParam));
66 (*callback)(hWnd);
67 return TRUE;
68 }
69 case WM_COMMAND:
70 {
71 if (wParam == IDCANCEL)
72 {
73 EndDialog(hWnd, wParam);
74 return TRUE;
75 }
76 break;
77 }
78 }
79 return FALSE;
80 }
81
82 DWORD RunThread(LPVOID param) 24 DWORD RunThread(LPVOID param)
83 { 25 {
84 std::auto_ptr<ThreadCallbackType> callback(reinterpret_cast<ThreadCallbackTy pe*>(param)); 26 std::auto_ptr<ThreadCallbackType> callback(reinterpret_cast<ThreadCallbackTy pe*>(param));
85 (*callback)(); 27 (*callback)();
86 return 0; 28 return 0;
87 } 29 }
88 30
89 std::wstring EscapeCommandLineArg(const std::wstring& arg) 31 std::wstring EscapeCommandLineArg(const std::wstring& arg)
90 { 32 {
91 // This does the inverse of CommandLineToArgvW(). See 33 // This does the inverse of CommandLineToArgvW(). See
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 } 76 }
135 } 77 }
136 78
137 Updater::Updater(AdblockPlus::JsEnginePtr jsEngine, const std::string& url) 79 Updater::Updater(AdblockPlus::JsEnginePtr jsEngine, const std::string& url)
138 : jsEngine(jsEngine), url(url), tempFile(GetAppDataPath() + L"\\update.msi") 80 : jsEngine(jsEngine), url(url), tempFile(GetAppDataPath() + L"\\update.msi")
139 { 81 {
140 } 82 }
141 83
142 void Updater::Update() 84 void Updater::Update()
143 { 85 {
144 Debug("Update available: " + url); 86 Debug("Downloading update: " + url);
145 87 ThreadCallbackType* callback = new ThreadCallbackType(std::bind(&Updater::Down load, this));
146 if (DialogBox(NULL, MAKEINTRESOURCE(IDD_UPDATEDIALOG), GetDesktopWindow(), 88 ::CreateThread(NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(&RunThread), callback, 0, NULL);
147 reinterpret_cast<DLGPROC>(&UpdateDlgProc)) == IDOK)
148 {
149 Debug("User accepted update");
150
151 DialogCallbackType* callback = new DialogCallbackType(std::bind(&Updater::St artDownload,
152 this, std::placeholders::_1));
153 int result = DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DOWNLOADDIALOG), GetDe sktopWindow(),
154 reinterpret_cast<DLGPROC>(&DownloadDlgProc),
155 reinterpret_cast<LPARAM>(callback));
156 if (result == DOWNLOAD_FAILED)
157 {
158 Dictionary* dict = Dictionary::GetInstance();
159 MessageBoxW(NULL,
160 dict->Lookup("updater", "download-error-neterror").c_str(),
161 dict->Lookup("updater", "download-error-title").c_str(),
162 0);
163 }
164 if (result != IDOK)
165 return;
166
167 if (!InstallUpdate(tempFile))
168 {
169 DebugLastError("Running updater failed");
170
171 Dictionary* dict = Dictionary::GetInstance();
172 MessageBoxW(NULL,
173 dict->Lookup("updater", "download-error-runerror").c_str(),
174 dict->Lookup("updater", "download-error-title").c_str(),
175 0);
176 }
177 }
178 } 89 }
179 90
180 void Updater::StartDownload(HWND dialog) 91 void Updater::Download()
181 {
182 this->dialog = dialog;
183 ThreadCallbackType* callback = new ThreadCallbackType(std::bind(&Updater::RunD ownload, this));
184 ::CreateThread(NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(&RunThread),
185 callback, 0, NULL);
186 }
187
188 void Updater::RunDownload()
189 { 92 {
190 AdblockPlus::ServerResponse response = jsEngine->GetWebRequest()->GET(url, Adb lockPlus::HeaderList()); 93 AdblockPlus::ServerResponse response = jsEngine->GetWebRequest()->GET(url, Adb lockPlus::HeaderList());
191 if (response.status != AdblockPlus::WebRequest::NS_OK || 94 if (response.status != AdblockPlus::WebRequest::NS_OK ||
192 response.responseStatus != 200) 95 response.responseStatus != 200)
193 { 96 {
194 std::stringstream ss; 97 std::stringstream ss;
195 ss << "Update download failed (status: " << response.status << ", "; 98 ss << "Update download failed (status: " << response.status << ", ";
196 ss << "response: " << response.responseStatus << ")"; 99 ss << "response: " << response.responseStatus << ")";
197 Debug(ss.str()); 100 Debug(ss.str());
198
199 EndDialog(dialog, DOWNLOAD_FAILED);
200 return; 101 return;
201 } 102 }
202 103
203 AdblockPlus::FileSystemPtr fileSystem = jsEngine->GetFileSystem(); 104 AdblockPlus::FileSystemPtr fileSystem = jsEngine->GetFileSystem();
204 std::string utfTempFile = ToUtf8String(tempFile); 105 std::string utfTempFile = ToUtf8String(tempFile);
205 try 106 try
206 { 107 {
207 // Remove left-overs from previous update attempts 108 // Remove left-overs from previous update attempts
208 fileSystem->Remove(utfTempFile); 109 fileSystem->Remove(utfTempFile);
209 } 110 }
210 catch (const std::exception&) 111 catch (const std::exception&)
211 { 112 {
212 } 113 }
213 114
214 try 115 try
215 { 116 {
216 std::tr1::shared_ptr<std::istream> fileData(new std::istringstream(response. responseText)); 117 std::tr1::shared_ptr<std::istream> fileData(new std::istringstream(response. responseText));
217 fileSystem->Write(utfTempFile, fileData); 118 fileSystem->Write(utfTempFile, fileData);
218 } 119 }
219 catch (const std::exception& e) 120 catch (const std::exception& e)
220 { 121 {
221 DebugException(e); 122 DebugException(e);
222 EndDialog(dialog, DOWNLOAD_FAILED);
223 return; 123 return;
224 } 124 }
225 125
226 EndDialog(dialog, IDOK); 126 OnDownloadSuccess();
227 } 127 }
128
129 void Updater::OnDownloadSuccess()
130 {
131 UpdateInstallDialog dialog;
132 bool shouldInstall = dialog.Show();
133 if (shouldInstall)
134 {
135 if (!InstallUpdate(tempFile))
136 {
137 DebugLastError("Failed to install update");
138 Dictionary* dictionary = Dictionary::GetInstance();
139 MessageBoxW(
140 0, dictionary->Lookup("updater", "install-error-text").c_str(),
141 dictionary->Lookup("updater", "install-error-title").c_str(), MB_OK);
Wladimir Palant 2013/08/01 09:58:24 Add MB_ICONEXCLAMATION flag?
Felix Dahlke 2013/08/02 10:48:01 Done.
142 }
143 }
144 }
OLDNEW

Powered by Google App Engine
This is Rietveld