OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/dom_ui/app_launcher_handler.h" | 5 #include "chrome/browser/dom_ui/app_launcher_handler.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "base/string_number_conversions.h" | 8 #include "base/string_number_conversions.h" |
9 #include "base/string_split.h" | 9 #include "base/string_split.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
12 #include "base/values.h" | 12 #include "base/values.h" |
13 #include "chrome/browser/app_launched_animation.h" | 13 #include "chrome/browser/app_launched_animation.h" |
| 14 #include "chrome/browser/dom_ui/shown_sections_handler.h" |
14 #include "chrome/browser/extensions/default_apps.h" | 15 #include "chrome/browser/extensions/default_apps.h" |
15 #include "chrome/browser/extensions/extension_prefs.h" | 16 #include "chrome/browser/extensions/extension_prefs.h" |
16 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
17 #include "chrome/browser/platform_util.h" | 18 #include "chrome/browser/platform_util.h" |
18 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/browser/tab_contents/tab_contents.h" | 20 #include "chrome/browser/tab_contents/tab_contents.h" |
20 #include "chrome/browser/ui/browser.h" | 21 #include "chrome/browser/ui/browser.h" |
21 #include "chrome/browser/ui/browser_list.h" | 22 #include "chrome/browser/ui/browser_list.h" |
22 #include "chrome/browser/ui/browser_window.h" | 23 #include "chrome/browser/ui/browser_window.h" |
23 #include "chrome/common/chrome_switches.h" | 24 #include "chrome/common/chrome_switches.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 | 69 |
69 CHECK(params.size() == 2); | 70 CHECK(params.size() == 2); |
70 | 71 |
71 return params.at(1) == "true"; | 72 return params.at(1) == "true"; |
72 } | 73 } |
73 | 74 |
74 } // namespace | 75 } // namespace |
75 | 76 |
76 AppLauncherHandler::AppLauncherHandler(ExtensionService* extension_service) | 77 AppLauncherHandler::AppLauncherHandler(ExtensionService* extension_service) |
77 : extensions_service_(extension_service), | 78 : extensions_service_(extension_service), |
78 promo_active_(false) { | 79 promo_active_(false), |
| 80 ignore_changes_(false) { |
79 } | 81 } |
80 | 82 |
81 AppLauncherHandler::~AppLauncherHandler() {} | 83 AppLauncherHandler::~AppLauncherHandler() {} |
82 | 84 |
83 // static | 85 // static |
84 void AppLauncherHandler::CreateAppInfo(const Extension* extension, | 86 void AppLauncherHandler::CreateAppInfo(const Extension* extension, |
85 ExtensionPrefs* extension_prefs, | 87 ExtensionPrefs* extension_prefs, |
86 DictionaryValue* value) { | 88 DictionaryValue* value) { |
87 value->Clear(); | 89 value->Clear(); |
88 value->SetString("id", extension->id()); | 90 value->SetString("id", extension->id()); |
(...skipping 15 matching lines...) Expand all Loading... |
104 int app_launch_index = extension_prefs->GetAppLaunchIndex(extension->id()); | 106 int app_launch_index = extension_prefs->GetAppLaunchIndex(extension->id()); |
105 if (app_launch_index == -1) { | 107 if (app_launch_index == -1) { |
106 // Make sure every app has a launch index (some predate the launch index). | 108 // Make sure every app has a launch index (some predate the launch index). |
107 app_launch_index = extension_prefs->GetNextAppLaunchIndex(); | 109 app_launch_index = extension_prefs->GetNextAppLaunchIndex(); |
108 extension_prefs->SetAppLaunchIndex(extension->id(), app_launch_index); | 110 extension_prefs->SetAppLaunchIndex(extension->id(), app_launch_index); |
109 } | 111 } |
110 value->SetInteger("app_launch_index", app_launch_index); | 112 value->SetInteger("app_launch_index", app_launch_index); |
111 } | 113 } |
112 | 114 |
113 // static | 115 // static |
114 bool AppLauncherHandler::HandlePing(const std::string& path) { | 116 bool AppLauncherHandler::HandlePing(Profile* profile, const std::string& path) { |
115 if (path.find(kLaunchWebStorePingURL) != std::string::npos) { | 117 bool is_web_store_ping = |
116 RecordWebStoreLaunch(IsPromoActive(path)); | 118 path.find(kLaunchWebStorePingURL) != std::string::npos; |
117 return true; | 119 bool is_app_launch_ping = |
118 } else if (path.find(kLaunchAppPingURL) != std::string::npos) { | 120 path.find(kLaunchAppPingURL) != std::string::npos; |
119 RecordAppLaunch(IsPromoActive(path)); | |
120 return true; | |
121 } | |
122 | 121 |
123 return false; | 122 // We get called for every URL in chrome://newtab/. Return false if it isn't |
| 123 // one we handle. |
| 124 if (!is_web_store_ping && !is_app_launch_ping) |
| 125 return false; |
| 126 |
| 127 bool is_promo_active = IsPromoActive(path); |
| 128 |
| 129 if (is_web_store_ping) |
| 130 RecordWebStoreLaunch(is_promo_active); |
| 131 else |
| 132 RecordAppLaunch(is_promo_active); |
| 133 |
| 134 if (is_promo_active) |
| 135 profile->GetExtensionService()->default_apps()->SetPromoHidden(); |
| 136 |
| 137 return true; |
124 } | 138 } |
125 | 139 |
126 DOMMessageHandler* AppLauncherHandler::Attach(DOMUI* dom_ui) { | 140 DOMMessageHandler* AppLauncherHandler::Attach(DOMUI* dom_ui) { |
127 // TODO(arv): Add initialization code to the Apps store etc. | 141 // TODO(arv): Add initialization code to the Apps store etc. |
128 return DOMMessageHandler::Attach(dom_ui); | 142 return DOMMessageHandler::Attach(dom_ui); |
129 } | 143 } |
130 | 144 |
131 void AppLauncherHandler::RegisterMessages() { | 145 void AppLauncherHandler::RegisterMessages() { |
132 dom_ui_->RegisterMessageCallback("getApps", | 146 dom_ui_->RegisterMessageCallback("getApps", |
133 NewCallback(this, &AppLauncherHandler::HandleGetApps)); | 147 NewCallback(this, &AppLauncherHandler::HandleGetApps)); |
134 dom_ui_->RegisterMessageCallback("launchApp", | 148 dom_ui_->RegisterMessageCallback("launchApp", |
135 NewCallback(this, &AppLauncherHandler::HandleLaunchApp)); | 149 NewCallback(this, &AppLauncherHandler::HandleLaunchApp)); |
136 dom_ui_->RegisterMessageCallback("setLaunchType", | 150 dom_ui_->RegisterMessageCallback("setLaunchType", |
137 NewCallback(this, &AppLauncherHandler::HandleSetLaunchType)); | 151 NewCallback(this, &AppLauncherHandler::HandleSetLaunchType)); |
138 dom_ui_->RegisterMessageCallback("uninstallApp", | 152 dom_ui_->RegisterMessageCallback("uninstallApp", |
139 NewCallback(this, &AppLauncherHandler::HandleUninstallApp)); | 153 NewCallback(this, &AppLauncherHandler::HandleUninstallApp)); |
140 dom_ui_->RegisterMessageCallback("hideAppsPromo", | 154 dom_ui_->RegisterMessageCallback("hideAppsPromo", |
141 NewCallback(this, &AppLauncherHandler::HandleHideAppsPromo)); | 155 NewCallback(this, &AppLauncherHandler::HandleHideAppsPromo)); |
142 dom_ui_->RegisterMessageCallback("createAppShortcut", | 156 dom_ui_->RegisterMessageCallback("createAppShortcut", |
143 NewCallback(this, &AppLauncherHandler::HandleCreateAppShortcut)); | 157 NewCallback(this, &AppLauncherHandler::HandleCreateAppShortcut)); |
144 } | 158 } |
145 | 159 |
146 void AppLauncherHandler::Observe(NotificationType type, | 160 void AppLauncherHandler::Observe(NotificationType type, |
147 const NotificationSource& source, | 161 const NotificationSource& source, |
148 const NotificationDetails& details) { | 162 const NotificationDetails& details) { |
| 163 if (ignore_changes_) |
| 164 return; |
| 165 |
149 switch (type.value) { | 166 switch (type.value) { |
150 case NotificationType::EXTENSION_LOADED: | 167 case NotificationType::EXTENSION_LOADED: |
151 case NotificationType::EXTENSION_UNLOADED: | 168 case NotificationType::EXTENSION_UNLOADED: |
152 if (dom_ui_->tab_contents()) | 169 if (dom_ui_->tab_contents()) |
153 HandleGetApps(NULL); | 170 HandleGetApps(NULL); |
154 break; | 171 break; |
155 case NotificationType::PREF_CHANGED: { | 172 case NotificationType::PREF_CHANGED: { |
156 if (!dom_ui_->tab_contents()) | 173 if (!dom_ui_->tab_contents()) |
157 break; | 174 break; |
158 | 175 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 #endif | 211 #endif |
195 | 212 |
196 dictionary->SetBoolean( | 213 dictionary->SetBoolean( |
197 "showLauncher", | 214 "showLauncher", |
198 extensions_service_->default_apps()->ShouldShowAppLauncher( | 215 extensions_service_->default_apps()->ShouldShowAppLauncher( |
199 extensions_service_->GetAppIds())); | 216 extensions_service_->GetAppIds())); |
200 } | 217 } |
201 | 218 |
202 void AppLauncherHandler::HandleGetApps(const ListValue* args) { | 219 void AppLauncherHandler::HandleGetApps(const ListValue* args) { |
203 DictionaryValue dictionary; | 220 DictionaryValue dictionary; |
204 FillAppDictionary(&dictionary); | |
205 | 221 |
206 // Tell the client whether to show the promo for this view. We don't do this | 222 // Tell the client whether to show the promo for this view. We don't do this |
207 // in the case of PREF_CHANGED because: | 223 // in the case of PREF_CHANGED because: |
208 // | 224 // |
209 // a) At that point in time, depending on the pref that changed, it can look | 225 // a) At that point in time, depending on the pref that changed, it can look |
210 // like the set of apps installed has changed, and we will mark the promo | 226 // like the set of apps installed has changed, and we will mark the promo |
211 // expired. | 227 // expired. |
212 // b) Conceptually, it doesn't really make sense to count a | 228 // b) Conceptually, it doesn't really make sense to count a |
213 // prefchange-triggered refresh as a promo 'view'. | 229 // prefchange-triggered refresh as a promo 'view'. |
214 DefaultApps* default_apps = extensions_service_->default_apps(); | 230 DefaultApps* default_apps = extensions_service_->default_apps(); |
215 if (default_apps->ShouldShowPromo(extensions_service_->GetAppIds())) { | 231 bool promo_just_expired = false; |
| 232 if (default_apps->ShouldShowPromo(extensions_service_->GetAppIds(), |
| 233 &promo_just_expired)) { |
216 dictionary.SetBoolean("showPromo", true); | 234 dictionary.SetBoolean("showPromo", true); |
217 default_apps->DidShowPromo(); | |
218 promo_active_ = true; | 235 promo_active_ = true; |
219 } else { | 236 } else { |
| 237 if (promo_just_expired) { |
| 238 ignore_changes_ = true; |
| 239 UninstallDefaultApps(); |
| 240 ignore_changes_ = false; |
| 241 ShownSectionsHandler::SetShownSection(dom_ui_->GetProfile()->GetPrefs(), |
| 242 THUMB); |
| 243 } |
220 dictionary.SetBoolean("showPromo", false); | 244 dictionary.SetBoolean("showPromo", false); |
221 promo_active_ = false; | 245 promo_active_ = false; |
222 } | 246 } |
223 | 247 |
| 248 FillAppDictionary(&dictionary); |
224 dom_ui_->CallJavascriptFunction(L"getAppsCallback", dictionary); | 249 dom_ui_->CallJavascriptFunction(L"getAppsCallback", dictionary); |
225 | 250 |
226 // First time we get here we set up the observer so that we can tell update | 251 // First time we get here we set up the observer so that we can tell update |
227 // the apps as they change. | 252 // the apps as they change. |
228 if (registrar_.IsEmpty()) { | 253 if (registrar_.IsEmpty()) { |
229 registrar_.Add(this, NotificationType::EXTENSION_LOADED, | 254 registrar_.Add(this, NotificationType::EXTENSION_LOADED, |
230 NotificationService::AllSources()); | 255 NotificationService::AllSources()); |
231 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, | 256 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, |
232 NotificationService::AllSources()); | 257 NotificationService::AllSources()); |
233 } | 258 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 extension_misc::LaunchContainer launch_container = | 305 extension_misc::LaunchContainer launch_container = |
281 extensions_service_->extension_prefs()->GetLaunchContainer( | 306 extensions_service_->extension_prefs()->GetLaunchContainer( |
282 extension, ExtensionPrefs::LAUNCH_REGULAR); | 307 extension, ExtensionPrefs::LAUNCH_REGULAR); |
283 | 308 |
284 TabContents* new_contents = Browser::OpenApplication( | 309 TabContents* new_contents = Browser::OpenApplication( |
285 profile, extension, launch_container, old_contents); | 310 profile, extension, launch_container, old_contents); |
286 | 311 |
287 if (new_contents != old_contents && browser->tab_count() > 1) | 312 if (new_contents != old_contents && browser->tab_count() > 1) |
288 browser->CloseTabContents(old_contents); | 313 browser->CloseTabContents(old_contents); |
289 | 314 |
290 if (extension_id != extension_misc::kWebStoreAppId) | 315 if (extension_id != extension_misc::kWebStoreAppId) { |
291 RecordAppLaunch(promo_active_); | 316 RecordAppLaunch(promo_active_); |
| 317 extensions_service_->default_apps()->SetPromoHidden(); |
| 318 } |
292 } | 319 } |
293 | 320 |
294 void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) { | 321 void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) { |
295 std::string extension_id; | 322 std::string extension_id; |
296 int launch_type; | 323 int launch_type; |
297 if (!args->GetString(0, &extension_id) || | 324 if (!args->GetString(0, &extension_id) || |
298 !ExtractInt(args, 1, &launch_type)) { | 325 !ExtractInt(args, 1, &launch_type)) { |
299 NOTREACHED(); | 326 NOTREACHED(); |
300 return; | 327 return; |
301 } | 328 } |
(...skipping 22 matching lines...) Expand all Loading... |
324 } | 351 } |
325 | 352 |
326 void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) { | 353 void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) { |
327 // If the user has intentionally hidden the promotion, we'll uninstall all the | 354 // If the user has intentionally hidden the promotion, we'll uninstall all the |
328 // default apps (we know the user hasn't installed any apps on their own at | 355 // default apps (we know the user hasn't installed any apps on their own at |
329 // this point, or the promotion wouldn't have been shown). | 356 // this point, or the promotion wouldn't have been shown). |
330 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, | 357 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram, |
331 extension_misc::PROMO_CLOSE, | 358 extension_misc::PROMO_CLOSE, |
332 extension_misc::PROMO_BUCKET_BOUNDARY); | 359 extension_misc::PROMO_BUCKET_BOUNDARY); |
333 | 360 |
334 DefaultApps* default_apps = extensions_service_->default_apps(); | 361 ShownSectionsHandler::SetShownSection(dom_ui_->GetProfile()->GetPrefs(), |
335 const ExtensionIdSet& app_ids = default_apps->default_apps(); | 362 THUMB); |
336 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); | 363 ignore_changes_ = true; |
337 iter != app_ids.end(); ++iter) { | 364 UninstallDefaultApps(); |
338 if (extensions_service_->GetExtensionById(*iter, true)) | |
339 extensions_service_->UninstallExtension(*iter, false); | |
340 } | |
341 | |
342 extensions_service_->default_apps()->SetPromoHidden(); | 365 extensions_service_->default_apps()->SetPromoHidden(); |
| 366 ignore_changes_ = false; |
| 367 HandleGetApps(NULL); |
343 } | 368 } |
344 | 369 |
345 void AppLauncherHandler::HandleCreateAppShortcut(const ListValue* args) { | 370 void AppLauncherHandler::HandleCreateAppShortcut(const ListValue* args) { |
346 std::string extension_id; | 371 std::string extension_id; |
347 if (!args->GetString(0, &extension_id)) { | 372 if (!args->GetString(0, &extension_id)) { |
348 NOTREACHED(); | 373 NOTREACHED(); |
349 return; | 374 return; |
350 } | 375 } |
351 | 376 |
352 const Extension* extension = | 377 const Extension* extension = |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 // We make this check for the case of minimized windows, unit tests, etc. | 436 // We make this check for the case of minimized windows, unit tests, etc. |
412 if (platform_util::IsVisible(dom_ui_->tab_contents()->GetNativeView()) && | 437 if (platform_util::IsVisible(dom_ui_->tab_contents()->GetNativeView()) && |
413 ui::Animation::ShouldRenderRichAnimation()) { | 438 ui::Animation::ShouldRenderRichAnimation()) { |
414 #if defined(OS_WIN) | 439 #if defined(OS_WIN) |
415 AppLaunchedAnimation::Show(extension, rect); | 440 AppLaunchedAnimation::Show(extension, rect); |
416 #else | 441 #else |
417 NOTIMPLEMENTED(); | 442 NOTIMPLEMENTED(); |
418 #endif | 443 #endif |
419 } | 444 } |
420 } | 445 } |
| 446 |
| 447 void AppLauncherHandler::UninstallDefaultApps() { |
| 448 DefaultApps* default_apps = extensions_service_->default_apps(); |
| 449 const ExtensionIdSet& app_ids = default_apps->default_apps(); |
| 450 for (ExtensionIdSet::const_iterator iter = app_ids.begin(); |
| 451 iter != app_ids.end(); ++iter) { |
| 452 if (extensions_service_->GetExtensionById(*iter, true)) |
| 453 extensions_service_->UninstallExtension(*iter, false); |
| 454 } |
| 455 } |
OLD | NEW |