OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "chrome/browser/chromeos/extensions/wallpaper_manager_api.h" | 5 #include "chrome/browser/chromeos/extensions/wallpaper_manager_api.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/json/json_writer.h" |
9 #include "base/path_service.h" | 10 #include "base/path_service.h" |
10 #include "chrome/browser/browser_process.h" | 11 #include "chrome/browser/browser_process.h" |
11 #include "chrome/browser/chromeos/login/user_manager.h" | 12 #include "chrome/browser/chromeos/login/user_manager.h" |
| 13 #include "chrome/browser/chromeos/login/wallpaper_manager.h" |
| 14 #include "chrome/browser/extensions/extension_event_router.h" |
12 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
13 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
14 #include "chrome/browser/profiles/profile_manager.h" | 17 #include "chrome/browser/profiles/profile_manager.h" |
15 #include "chrome/browser/ui/browser.h" | 18 #include "chrome/browser/ui/browser.h" |
16 #include "chrome/browser/ui/browser_finder.h" | 19 #include "chrome/browser/ui/browser_finder.h" |
17 #include "chrome/browser/ui/chrome_pages.h" | 20 #include "chrome/browser/ui/chrome_pages.h" |
18 #include "chrome/browser/ui/extensions/application_launch.h" | 21 #include "chrome/browser/ui/extensions/application_launch.h" |
19 #include "chrome/common/chrome_paths.h" | 22 #include "chrome/common/chrome_paths.h" |
20 #include "chrome/common/chrome_switches.h" | 23 #include "chrome/common/chrome_switches.h" |
21 #include "chrome/common/url_constants.h" | 24 #include "chrome/common/url_constants.h" |
22 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
| 26 #include "net/url_request/url_fetcher.h" |
| 27 #include "net/url_request/url_fetcher_delegate.h" |
| 28 #include "net/url_request/url_request_status.h" |
| 29 #include "grit/generated_resources.h" |
| 30 #include "ui/base/l10n/l10n_util.h" |
23 | 31 |
24 using content::BrowserThread; | 32 using content::BrowserThread; |
25 | 33 |
26 const char kWallpaperManagerDomain[] = "obklkkbkpaoaejdabbfldmcfplpdgolj"; | 34 const char kWallpaperManagerDomain[] = "obklkkbkpaoaejdabbfldmcfplpdgolj"; |
27 | 35 |
| 36 namespace { |
| 37 |
| 38 std::string GetIDFromCode(WallpaperErrorCode code) { |
| 39 switch (code) { |
| 40 case HTTP_BAD_REQUEST: |
| 41 return "HTTP_BAD_REQUEST"; |
| 42 case HTTP_UNAUTHORIZED: |
| 43 return "HTTP_UNAUTHORIZED"; |
| 44 case HTTP_FORBIDDEN: |
| 45 return "HTTP_FORBIDDEN"; |
| 46 case HTTP_NOT_FOUND: |
| 47 return "HTTP_NOT_FOUND"; |
| 48 case HTTP_CONFLICT: |
| 49 return "HTTP_CONFLICT"; |
| 50 case HTTP_LENGTH_REQUIRED: |
| 51 return "HTTP_LENGTH_REQUIRED"; |
| 52 case HTTP_PRECONDITION: |
| 53 return "HTTP_PRECONDITION"; |
| 54 case HTTP_INTERNAL_SERVER_ERROR: |
| 55 return "HTTP_INTERNAL_SERVER_ERROR"; |
| 56 case HTTP_SERVICE_UNAVAILABLE: |
| 57 return "HTTP_SERVICE_UNAVAILABLE"; |
| 58 case WALLPAPER_NO_CONNECTION: |
| 59 return "WALLPAPER_NO_CONNECTION"; |
| 60 case WALLPAPER_FILE_ERROR: |
| 61 return "WALLPAPER_FILE_ERROR"; |
| 62 default: |
| 63 return "DOWNLOAD_DEFAULT_ERROR"; |
| 64 } |
| 65 } |
| 66 |
| 67 } // namespace |
| 68 |
| 69 namespace events { |
| 70 |
| 71 const char kDownloadStartEvent[] = |
| 72 "wallpaperManagerPrivate.onDownloadStart"; |
| 73 const char kDownloadProgressEvent[] = |
| 74 "wallpaperManagerPrivate.onDownloadProgress"; |
| 75 const char kDownloadDoneEvent[] = |
| 76 "wallpaperManagerPrivate.onDownloadDone"; |
| 77 const char kDownloadErrorEvent[] = |
| 78 "wallpaperManagerPrivate.onDownloadError"; |
| 79 |
| 80 } // namespace events |
| 81 |
28 namespace wallpaper_manager_util { | 82 namespace wallpaper_manager_util { |
29 | 83 |
30 void OpenWallpaperManager() { | 84 void OpenWallpaperManager() { |
31 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); | 85 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); |
32 // Hides the new UI container behind a flag. | 86 // Hides the new UI container behind a flag. |
33 if (CommandLine::ForCurrentProcess()->HasSwitch( | 87 if (CommandLine::ForCurrentProcess()->HasSwitch( |
34 switches::kExperimentalWallpaperUI)) { | 88 switches::kExperimentalWallpaperUI)) { |
35 std::string url = chrome::kChromeUIWallpaperURL; | 89 std::string url = chrome::kChromeUIWallpaperURL; |
36 ExtensionService* service = profile->GetExtensionService(); | 90 ExtensionService* service = profile->GetExtensionService(); |
37 if (!service) | 91 if (!service) |
38 return; | 92 return; |
39 | 93 |
40 const extensions::Extension* extension = | 94 const extensions::Extension* extension = |
41 service->GetExtensionById(kWallpaperManagerDomain, false); | 95 service->GetExtensionById(kWallpaperManagerDomain, false); |
42 if (!extension) | 96 if (!extension) |
43 return; | 97 return; |
44 | 98 |
45 application_launch::LaunchParams params(profile, extension, | 99 application_launch::LaunchParams params(profile, extension, |
46 extension_misc::LAUNCH_WINDOW, | 100 extension_misc::LAUNCH_WINDOW, |
47 NEW_FOREGROUND_TAB); | 101 NEW_FOREGROUND_TAB); |
48 params.override_url = GURL(url); | 102 params.override_url = GURL(url); |
49 application_launch::OpenApplication(params); | 103 application_launch::OpenApplication(params); |
50 } else { | 104 } else { |
51 Browser* browser = browser::FindOrCreateTabbedBrowser( | 105 Browser* browser = browser::FindOrCreateTabbedBrowser( |
52 ProfileManager::GetDefaultProfileOrOffTheRecord()); | 106 ProfileManager::GetDefaultProfileOrOffTheRecord()); |
53 chrome::ShowSettingsSubPage(browser, "setWallpaper"); | 107 chrome::ShowSettingsSubPage(browser, "setWallpaper"); |
54 } | 108 } |
55 } | 109 } |
56 | 110 |
57 } // namespace wallpaper_manager_util | 111 } //namespace wallpaper_manager_util |
| 112 |
| 113 bool WallpaperManagerStringsFunction::RunImpl() { |
| 114 DictionaryValue* dict = new DictionaryValue(); |
| 115 SetResult(dict); |
| 116 |
| 117 #define SET_STRING(ns, id) \ |
| 118 dict->SetString(#id, l10n_util::GetStringUTF16(ns##_##id)) |
| 119 SET_STRING(IDS_WALLPAPER_MANAGER, SEARCH_TEXT_LABEL); |
| 120 SET_STRING(IDS_WALLPAPER_MANAGER, AUTHOR_LABEL); |
| 121 SET_STRING(IDS_WALLPAPER_MANAGER, CUSTOM_CATEGORY_LABEL); |
| 122 SET_STRING(IDS_WALLPAPER_MANAGER, SELECT_CUSTOM_LABEL); |
| 123 SET_STRING(IDS_WALLPAPER_MANAGER, POSITION_LABEL); |
| 124 SET_STRING(IDS_WALLPAPER_MANAGER, COLOR_LABEL); |
| 125 SET_STRING(IDS_WALLPAPER_MANAGER, PREVIEW_LABEL); |
| 126 SET_STRING(IDS_WALLPAPER_MANAGER, HTTP_BAD_REQUEST); |
| 127 SET_STRING(IDS_WALLPAPER_MANAGER, HTTP_UNAUTHORIZED); |
| 128 SET_STRING(IDS_WALLPAPER_MANAGER, HTTP_FORBIDDEN); |
| 129 SET_STRING(IDS_WALLPAPER_MANAGER, HTTP_NOT_FOUND); |
| 130 SET_STRING(IDS_WALLPAPER_MANAGER, HTTP_CONFLICT); |
| 131 SET_STRING(IDS_WALLPAPER_MANAGER, HTTP_LENGTH_REQUIRED); |
| 132 SET_STRING(IDS_WALLPAPER_MANAGER, HTTP_PRECONDITION); |
| 133 SET_STRING(IDS_WALLPAPER_MANAGER, HTTP_INTERNAL_SERVER_ERROR); |
| 134 SET_STRING(IDS_WALLPAPER_MANAGER, HTTP_SERVICE_UNAVAILABLE); |
| 135 SET_STRING(IDS_WALLPAPER_MANAGER, WALLPAPER_NO_CONNECTION); |
| 136 SET_STRING(IDS_WALLPAPER_MANAGER, WALLPAPER_FILE_ERROR); |
| 137 SET_STRING(IDS_WALLPAPER_MANAGER, DOWNLOAD_DEFAULT_ERROR); |
| 138 SET_STRING(IDS_OPTIONS, SET_WALLPAPER_DAILY); |
| 139 #undef SET_STRING |
| 140 |
| 141 ChromeURLDataManager::DataSource::SetFontAndTextDirection(dict); |
| 142 |
| 143 return true; |
| 144 } |
| 145 |
| 146 // static |
| 147 WallpaperManagerSetWallpaperFunction::WallpaperFetcher* |
| 148 WallpaperManagerSetWallpaperFunction::fetcher_; |
| 149 |
| 150 WallpaperManagerSetWallpaperFunction::WallpaperFetcher::WallpaperFetcher( |
| 151 scoped_refptr<WallpaperManagerSetWallpaperFunction> function) |
| 152 : function_(function) { |
| 153 } |
| 154 |
| 155 void WallpaperManagerSetWallpaperFunction::WallpaperFetcher::Cancel() { |
| 156 fetcher_.reset(); |
| 157 delete this; |
| 158 } |
| 159 |
| 160 void WallpaperManagerSetWallpaperFunction::WallpaperFetcher::Start( |
| 161 const GURL& wallpaper_url, const FilePath& file_path) { |
| 162 fetcher_.reset(net::URLFetcher::Create(wallpaper_url, |
| 163 net::URLFetcher::GET, |
| 164 this)); |
| 165 fetcher_->SetRequestContext( |
| 166 g_browser_process->system_request_context()); |
| 167 |
| 168 fetcher_->SaveResponseToFileAtPath( |
| 169 file_path, |
| 170 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); |
| 171 fetcher_->Start(); |
| 172 } |
| 173 |
| 174 void WallpaperManagerSetWallpaperFunction::WallpaperFetcher::OnURLFetchComplete( |
| 175 const net::URLFetcher* source) { |
| 176 function_->OnDownloadComplete(source); |
| 177 delete this; |
| 178 } |
| 179 |
| 180 void WallpaperManagerSetWallpaperFunction::WallpaperFetcher |
| 181 ::OnURLFetchDownloadProgress(const net::URLFetcher* source, |
| 182 int64 current, |
| 183 int64 total) { |
| 184 if (source == fetcher_.get()) |
| 185 function_->OnDownloadProgress(source, current, total); |
| 186 } |
| 187 |
| 188 WallpaperManagerSetWallpaperFunction::~WallpaperManagerSetWallpaperFunction() { |
| 189 } |
| 190 |
| 191 bool WallpaperManagerSetWallpaperFunction::RunImpl() { |
| 192 // First param is url of the selected wallpaper. |
| 193 std::string url; |
| 194 if (!args_->GetString(0, &url) || url.empty()) |
| 195 return false; |
| 196 // Second param is the default layout of the selected wallpaper. |
| 197 std::string layout_string; |
| 198 if (!args_->GetString(1, &layout_string) || layout_string.empty()) { |
| 199 return false; |
| 200 } |
| 201 layout_ = ash::GetLayoutEnum(layout_string.c_str()); |
| 202 |
| 203 // Gets email address while at UI thread. |
| 204 email_ = chromeos::UserManager::Get()->GetLoggedInUser().email(); |
| 205 |
| 206 BrowserThread::PostTask( |
| 207 BrowserThread::FILE, FROM_HERE, |
| 208 base::Bind( |
| 209 &WallpaperManagerSetWallpaperFunction::RequestOnFileThread, |
| 210 this, url)); |
| 211 // Will finish asynchronously. |
| 212 return true; |
| 213 } |
| 214 |
| 215 void WallpaperManagerSetWallpaperFunction::OnDownloadComplete( |
| 216 const net::URLFetcher* source) { |
| 217 WallpaperErrorCode code = GetErrorCode(source); |
| 218 if (code != HTTP_SUCCESS) { |
| 219 DispatchErrorEvent(code); |
| 220 fetcher_ = NULL; |
| 221 return; |
| 222 } |
| 223 FilePath temp_file; |
| 224 if (code == HTTP_SUCCESS && |
| 225 !source->GetResponseAsFilePath(true, &temp_file)) { |
| 226 code = WALLPAPER_FILE_ERROR; |
| 227 DispatchErrorEvent(code); |
| 228 fetcher_ = NULL; |
| 229 return; |
| 230 } |
| 231 |
| 232 profile_->GetExtensionEventRouter()->DispatchEventToExtension( |
| 233 std::string(kWallpaperManagerDomain), |
| 234 events::kDownloadDoneEvent, |
| 235 "[]", profile_, GURL()); |
| 236 |
| 237 FilePath path = wallpaper_dir_.Append( |
| 238 source->GetOriginalURL().ExtractFileName()); |
| 239 |
| 240 chromeos::WallpaperManager::Get()->SetWallpaperFromFile(email_, |
| 241 path.value(), |
| 242 layout_); |
| 243 |
| 244 fetcher_ = NULL; |
| 245 } |
| 246 |
| 247 void WallpaperManagerSetWallpaperFunction::OnDownloadProgress( |
| 248 const net::URLFetcher* source, |
| 249 int64 current, |
| 250 int64 total) { |
| 251 if (current >= bytes_wallpaper_download_progress_last_reported_ + |
| 252 kBytesWallpaperDownloadProgressReportInterval) { |
| 253 bytes_wallpaper_download_progress_last_reported_ = current; |
| 254 base::TimeDelta time_remaining; |
| 255 if (current > 0) { |
| 256 const base::TimeDelta diff = |
| 257 base::TimeTicks::Now() - tick_wallpaper_download_start_; |
| 258 time_remaining = diff*(total - current)/current; |
| 259 |
| 260 DictionaryValue* dict = new DictionaryValue(); |
| 261 dict->SetInteger("remainingTime", time_remaining.InMilliseconds()); |
| 262 dict->SetDouble("progress", static_cast<double>(current) / total); |
| 263 ListValue args; |
| 264 args.Append(dict); |
| 265 std::string json_args; |
| 266 base::JSONWriter::Write(&args, &json_args); |
| 267 profile_->GetExtensionEventRouter()->DispatchEventToExtension( |
| 268 std::string(kWallpaperManagerDomain), |
| 269 events::kDownloadProgressEvent, |
| 270 json_args, profile_, GURL()); |
| 271 } |
| 272 } |
| 273 } |
| 274 |
| 275 void WallpaperManagerSetWallpaperFunction::RequestOnFileThread( |
| 276 const std::string& source_url) { |
| 277 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 278 CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS, &wallpaper_dir_)); |
| 279 |
| 280 GURL wallpaper_url(source_url); |
| 281 if (!file_util::DirectoryExists(wallpaper_dir_) && |
| 282 !file_util::CreateDirectory(wallpaper_dir_)) { |
| 283 DispatchErrorEvent(WALLPAPER_FILE_ERROR); |
| 284 return; |
| 285 } |
| 286 |
| 287 FilePath file_path = wallpaper_dir_.Append(wallpaper_url.ExtractFileName()); |
| 288 |
| 289 // If the wallpaper was already downloaded, use it immediately. |
| 290 if (file_util::PathExists(file_path)) { |
| 291 BrowserThread::PostTask( |
| 292 BrowserThread::UI, FROM_HERE, |
| 293 base::Bind( |
| 294 &WallpaperManagerSetWallpaperFunction::SetWallpaperOnUIThread, |
| 295 this, |
| 296 file_path)); |
| 297 return; |
| 298 } |
| 299 |
| 300 BrowserThread::PostTask( |
| 301 BrowserThread::UI, FROM_HERE, |
| 302 base::Bind( |
| 303 &WallpaperManagerSetWallpaperFunction::SetupFetcherOnUIThread, |
| 304 this, |
| 305 wallpaper_url)); |
| 306 } |
| 307 |
| 308 void WallpaperManagerSetWallpaperFunction::SetWallpaperOnUIThread( |
| 309 const FilePath& file_path) { |
| 310 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 311 chromeos::WallpaperManager::Get()->SetWallpaperFromFile(email_, |
| 312 file_path.value(), |
| 313 layout_); |
| 314 } |
| 315 |
| 316 void WallpaperManagerSetWallpaperFunction::SetupFetcherOnUIThread( |
| 317 const GURL& wallpaper_url) { |
| 318 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 319 tick_wallpaper_download_start_ = base::TimeTicks::Now(); |
| 320 bytes_wallpaper_download_progress_last_reported_ = 0; |
| 321 |
| 322 if (fetcher_) |
| 323 fetcher_->Cancel(); |
| 324 fetcher_ = new WallpaperFetcher(this); |
| 325 FilePath file_path = wallpaper_dir_.Append(wallpaper_url.ExtractFileName()); |
| 326 fetcher_->Start(wallpaper_url, file_path); |
| 327 |
| 328 profile_->GetExtensionEventRouter()->DispatchEventToExtension( |
| 329 std::string(kWallpaperManagerDomain), |
| 330 events::kDownloadStartEvent, |
| 331 "[]", profile_, GURL()); |
| 332 } |
| 333 |
| 334 WallpaperErrorCode WallpaperManagerSetWallpaperFunction::GetErrorCode( |
| 335 const net::URLFetcher* source) const { |
| 336 WallpaperErrorCode code = static_cast<WallpaperErrorCode>( |
| 337 source->GetResponseCode()); |
| 338 if (code == HTTP_SUCCESS && !source->GetStatus().is_success()) { |
| 339 // If the HTTP response code is SUCCESS yet the URL request failed, it is |
| 340 // likely that the failure is due to loss of connection. |
| 341 code = WALLPAPER_NO_CONNECTION; |
| 342 } |
| 343 return code; |
| 344 } |
| 345 |
| 346 void WallpaperManagerSetWallpaperFunction::DispatchErrorEvent( |
| 347 WallpaperErrorCode code) { |
| 348 DictionaryValue* dict = new DictionaryValue(); |
| 349 dict->SetString("errorMessageID", GetIDFromCode(code)); |
| 350 ListValue args; |
| 351 args.Append(dict); |
| 352 std::string json_args; |
| 353 base::JSONWriter::Write(&args, &json_args); |
| 354 profile_->GetExtensionEventRouter()->DispatchEventToExtension( |
| 355 std::string(kWallpaperManagerDomain), |
| 356 events::kDownloadErrorEvent, |
| 357 json_args, profile_, GURL()); |
| 358 } |
OLD | NEW |