Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: chrome/browser/background/background_contents_service.cc

Issue 23427003: Reload force-installed extensions on crash/force-close (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/background/background_contents_service.h" 5 #include "chrome/browser/background/background_contents_service.h"
6 6
7 #include "apps/app_load_service.h" 7 #include "apps/app_load_service.h"
8 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 #include "ui/gfx/image/image.h" 47 #include "ui/gfx/image/image.h"
48 48
49 using content::SiteInstance; 49 using content::SiteInstance;
50 using content::WebContents; 50 using content::WebContents;
51 using extensions::BackgroundInfo; 51 using extensions::BackgroundInfo;
52 using extensions::Extension; 52 using extensions::Extension;
53 using extensions::UnloadedExtensionInfo; 53 using extensions::UnloadedExtensionInfo;
54 54
55 namespace { 55 namespace {
56 56
57 const char kNotificationPrefix[] = "app.background.crashed."; 57 const char kCrashNotificationPrefix[] = "app.background.crashed.";
58 const char kMisbehaveNotificationPrefix[] = "app.background.misbehaved.";
59
60 /** No. of recent crashes required to trigger an extension-misbehave popup **/
bartfab (slow) 2013/08/26 13:26:53 Nit 1: Do not use abbreviations: No. => Number Nit
anitawoodruff 2013/08/26 21:45:23 Done.
61 const unsigned int kNCrashesShouldNotify = 5;
bartfab (slow) 2013/08/26 13:26:53 Nit: This constant does not follow the usual Chrom
anitawoodruff 2013/08/26 21:45:23 Done.
58 62
59 void CloseBalloon(const std::string& id) { 63 void CloseBalloon(const std::string& id) {
60 g_browser_process->notification_ui_manager()->CancelById(id); 64 g_browser_process->notification_ui_manager()->CancelById(id);
61 } 65 }
62 66
63 void ScheduleCloseBalloon(const std::string& extension_id) { 67 void ScheduleCloseBalloon(const std::string& id) {
bartfab (slow) 2013/08/26 13:26:53 Nit 1: "extension_id" identifies an extension; eas
anitawoodruff 2013/08/26 21:45:23 Done - is prefixed_extension_id ok? Or should I ma
bartfab (slow) 2013/08/27 09:21:29 |prefixed_extension_id| is an accurate description
anitawoodruff 2013/08/27 10:00:51 Done.
64 if (!base::MessageLoop::current()) // For unit_tests 68 if (!base::MessageLoop::current()) // For unit_tests
65 return; 69 return;
66 base::MessageLoop::current()->PostTask( 70 base::MessageLoop::current()->PostTask(
67 FROM_HERE, base::Bind(&CloseBalloon, kNotificationPrefix + extension_id)); 71 FROM_HERE, base::Bind(&CloseBalloon, id));
72 }
73
74 void ScheduleCloseCrashBalloon(const std::string& extension_id) {
75 ScheduleCloseBalloon(kCrashNotificationPrefix + extension_id);
76 }
77
78 void ScheduleCloseBalloons(const std::string& extension_id) {
79 ScheduleCloseBalloon(kMisbehaveNotificationPrefix + extension_id);
80 ScheduleCloseBalloon(kCrashNotificationPrefix + extension_id);
68 } 81 }
69 82
70 class CrashNotificationDelegate : public NotificationDelegate { 83 class CrashNotificationDelegate : public NotificationDelegate {
71 public: 84 public:
72 CrashNotificationDelegate(Profile* profile, 85 CrashNotificationDelegate(Profile* profile,
73 const Extension* extension) 86 const Extension* extension)
74 : profile_(profile), 87 : profile_(profile),
75 is_hosted_app_(extension->is_hosted_app()), 88 is_hosted_app_(extension->is_hosted_app()),
76 is_platform_app_(extension->is_platform_app()), 89 is_platform_app_(extension->is_platform_app()),
77 extension_id_(extension->id()) { 90 extension_id_(extension->id()) {
(...skipping 22 matching lines...) Expand all
100 service->LoadBackgroundContentsForExtension(profile_, 113 service->LoadBackgroundContentsForExtension(profile_,
101 copied_extension_id); 114 copied_extension_id);
102 } else if (is_platform_app_) { 115 } else if (is_platform_app_) {
103 apps::AppLoadService::Get(profile_)-> 116 apps::AppLoadService::Get(profile_)->
104 RestartApplication(copied_extension_id); 117 RestartApplication(copied_extension_id);
105 } else { 118 } else {
106 extensions::ExtensionSystem::Get(profile_)->extension_service()-> 119 extensions::ExtensionSystem::Get(profile_)->extension_service()->
107 ReloadExtension(copied_extension_id); 120 ReloadExtension(copied_extension_id);
108 } 121 }
109 122
110 // Closing the balloon here should be OK, but it causes a crash on Mac 123 // Closing the balloon here should be OK, but it causes a crash on Mac
bartfab (slow) 2013/08/26 13:26:53 Nit: "the balloon" is no longer unambiguous.
anitawoodruff 2013/08/26 21:45:23 Done.
111 // http://crbug.com/78167 124 // http://crbug.com/78167
112 ScheduleCloseBalloon(copied_extension_id); 125 ScheduleCloseCrashBalloon(copied_extension_id);
113 } 126 }
114 127
115 virtual bool HasClickedListener() OVERRIDE { return true; } 128 virtual bool HasClickedListener() OVERRIDE { return true; }
116 129
117 virtual std::string id() const OVERRIDE { 130 virtual std::string id() const OVERRIDE {
118 return kNotificationPrefix + extension_id_; 131 return kCrashNotificationPrefix + extension_id_;
119 } 132 }
120 133
121 virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE { 134 virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE {
122 return NULL; 135 return NULL;
123 } 136 }
124 137
125 private: 138 private:
126 virtual ~CrashNotificationDelegate() {} 139 virtual ~CrashNotificationDelegate() {}
127 140
128 Profile* profile_; 141 Profile* profile_;
129 bool is_hosted_app_; 142 bool is_hosted_app_;
130 bool is_platform_app_; 143 bool is_platform_app_;
131 std::string extension_id_; 144 std::string extension_id_;
132 145
133 DISALLOW_COPY_AND_ASSIGN(CrashNotificationDelegate); 146 DISALLOW_COPY_AND_ASSIGN(CrashNotificationDelegate);
134 }; 147 };
135 148
149 class MisbehaveNotificationDelegate : public NotificationDelegate {
bartfab (slow) 2013/08/26 13:26:53 Nit 1: #include "chrome/browser/notifications/noti
anitawoodruff 2013/08/26 21:45:23 Done.
150 public:
151 explicit MisbehaveNotificationDelegate(const Extension* extension)
152 : extension_id_(extension->id()) {
153 }
154
155 virtual void Display() OVERRIDE {}
156
157 virtual void Error() OVERRIDE {}
158
159 virtual void Close(bool by_user) OVERRIDE {}
160
161 virtual void Click() OVERRIDE {}
162
163 virtual bool HasClickedListener() OVERRIDE { return true; }
164
165 virtual std::string id() const OVERRIDE {
166 return kMisbehaveNotificationPrefix + extension_id_;
167 }
168
169 virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE {
170 return NULL;
171 }
172
173 private:
174 virtual ~MisbehaveNotificationDelegate() {}
175
176 std::string extension_id_;
177
178 DISALLOW_COPY_AND_ASSIGN(MisbehaveNotificationDelegate);
179 };
180
136 #if defined(ENABLE_NOTIFICATIONS) 181 #if defined(ENABLE_NOTIFICATIONS)
137 void NotificationImageReady( 182 void NotificationImageReady(
138 const std::string extension_name, 183 const std::string extension_name,
139 const string16 message, 184 const string16 message,
140 const GURL extension_url, 185 const GURL extension_url,
141 scoped_refptr<CrashNotificationDelegate> delegate, 186 scoped_refptr<NotificationDelegate> delegate,
142 Profile* profile, 187 Profile* profile,
143 const gfx::Image& icon) { 188 const gfx::Image& icon) {
144 gfx::Image notification_icon(icon); 189 gfx::Image notification_icon(icon);
145 if (icon.IsEmpty()) { 190 if (icon.IsEmpty()) {
146 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 191 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
147 notification_icon = rb.GetImageNamed(IDR_EXTENSION_DEFAULT_ICON); 192 notification_icon = rb.GetImageNamed(IDR_EXTENSION_DEFAULT_ICON);
148 } 193 }
149 string16 title; // no notification title 194 string16 title; // no notification title
150 DesktopNotificationService::AddIconNotification(extension_url, 195 DesktopNotificationService::AddIconNotification(extension_url,
151 title, 196 title,
152 message, 197 message,
153 notification_icon, 198 notification_icon,
154 string16(), 199 string16(),
155 delegate.get(), 200 delegate.get(),
156 profile); 201 profile);
157 } 202 }
158 #endif 203 #endif
159 204
160 void ShowBalloon(const Extension* extension, Profile* profile) { 205 void ReloadExtension(const Extension* extension, Profile* profile) {
206 extensions::ExtensionSystem* extensionSystem =
207 extensions::ExtensionSystem::Get(profile);
208 if (extensionSystem && extensionSystem->extension_service())
209 extensionSystem->extension_service()->ReloadExtension(extension->id());
210 }
211
212 void ShowBalloon(const Extension* extension, Profile* profile, bool isForced) {
bartfab (slow) 2013/08/26 13:26:53 Nit: Add a comment explaining the parameters. "isF
anitawoodruff 2013/08/26 21:45:23 Done.
161 #if defined(ENABLE_NOTIFICATIONS) 213 #if defined(ENABLE_NOTIFICATIONS)
162 string16 message = l10n_util::GetStringFUTF16( 214 string16 message;
163 extension->is_app() ? IDS_BACKGROUND_CRASHED_APP_BALLOON_MESSAGE : 215 if (isForced) {
164 IDS_BACKGROUND_CRASHED_EXTENSION_BALLOON_MESSAGE, 216 message = l10n_util::GetStringFUTF16(
165 UTF8ToUTF16(extension->name())); 217 extension->is_app() ?
166 218 IDS_BACKGROUND_MISBEHAVING_APP_BALLOON_MESSAGE :
219 IDS_BACKGROUND_MISBEHAVING_EXTENSION_BALLOON_MESSAGE,
220 UTF8ToUTF16(extension->name()));
221 } else {
222 message = l10n_util::GetStringFUTF16(
223 extension->is_app() ? IDS_BACKGROUND_CRASHED_APP_BALLOON_MESSAGE :
224 IDS_BACKGROUND_CRASHED_EXTENSION_BALLOON_MESSAGE,
225 UTF8ToUTF16(extension->name()));
226 }
167 extension_misc::ExtensionIcons size(extension_misc::EXTENSION_ICON_MEDIUM); 227 extension_misc::ExtensionIcons size(extension_misc::EXTENSION_ICON_MEDIUM);
168 extensions::ExtensionResource resource = 228 extensions::ExtensionResource resource =
169 extensions::IconsInfo::GetIconResource( 229 extensions::IconsInfo::GetIconResource(
170 extension, size, ExtensionIconSet::MATCH_SMALLER); 230 extension, size, ExtensionIconSet::MATCH_SMALLER);
171 scoped_refptr<CrashNotificationDelegate> delegate = 231 scoped_refptr<NotificationDelegate> delegate = NULL;
bartfab (slow) 2013/08/26 13:26:53 Nit 1: You could set the delegate in the if-block
anitawoodruff 2013/08/26 21:45:23 Done.
172 new CrashNotificationDelegate(profile, extension); 232 if (isForced)
233 delegate = new MisbehaveNotificationDelegate(extension);
234 else
235 delegate = new CrashNotificationDelegate(profile, extension);
173 // We can't just load the image in the Observe method below because, despite 236 // We can't just load the image in the Observe method below because, despite
174 // what this method is called, it may call the callback synchronously. 237 // what this method is called, it may call the callback synchronously.
175 // However, it's possible that the extension went away during the interim, 238 // However, it's possible that the extension went away during the interim,
176 // so we'll bind all the pertinent data here. 239 // so we'll bind all the pertinent data here.
177 extensions::ImageLoader::Get(profile)->LoadImageAsync( 240 extensions::ImageLoader::Get(profile)->LoadImageAsync(
178 extension, 241 extension,
179 resource, 242 resource,
180 gfx::Size(size, size), 243 gfx::Size(size, size),
181 base::Bind( 244 base::Bind(
182 &NotificationImageReady, 245 &NotificationImageReady,
(...skipping 15 matching lines...) Expand all
198 // 261 //
199 // kRegisteredBackgroundContents: 262 // kRegisteredBackgroundContents:
200 // DictionaryValue { 263 // DictionaryValue {
201 // <appid_1>: { "url": <url1>, "name": <frame_name> }, 264 // <appid_1>: { "url": <url1>, "name": <frame_name> },
202 // <appid_2>: { "url": <url2>, "name": <frame_name> }, 265 // <appid_2>: { "url": <url2>, "name": <frame_name> },
203 // ... etc ... 266 // ... etc ...
204 // } 267 // }
205 const char kUrlKey[] = "url"; 268 const char kUrlKey[] = "url";
206 const char kFrameNameKey[] = "name"; 269 const char kFrameNameKey[] = "name";
207 270
271 /** Delay (in seconds) before restarting a forced extension that crashed **/
bartfab (slow) 2013/08/26 13:26:53 Nit 1: s/forced/force-installed/ Nit 2: Move the c
anitawoodruff 2013/08/26 21:45:23 Done.
272 base::TimeDelta BackgroundContentsService::restart_delay_ =
273 base::TimeDelta::FromSeconds(3);
274
275 /** Seconds since a crash-reload during which we listen for further crashes **/
bartfab (slow) 2013/08/26 13:26:53 This comment is not quite correct. With the defaul
anitawoodruff 2013/08/26 21:45:23 I know it's not, but I can't for the life of me th
bartfab (slow) 2013/08/27 09:21:29 It is OK to have a long comment if a variable is u
276 base::TimeDelta BackgroundContentsService::crash_window_ =
277 base::TimeDelta::FromSeconds(1);
278
208 BackgroundContentsService::BackgroundContentsService( 279 BackgroundContentsService::BackgroundContentsService(
209 Profile* profile, const CommandLine* command_line) 280 Profile* profile, const CommandLine* command_line)
210 : prefs_(NULL) { 281 : prefs_(NULL) {
211 // Don't load/store preferences if the proper switch is not enabled, or if 282 // Don't load/store preferences if the proper switch is not enabled, or if
212 // the parent profile is incognito. 283 // the parent profile is incognito.
213 if (!profile->IsOffTheRecord() && 284 if (!profile->IsOffTheRecord() &&
214 !command_line->HasSwitch(switches::kDisableRestoreBackgroundContents)) 285 !command_line->HasSwitch(switches::kDisableRestoreBackgroundContents))
215 prefs_ = profile->GetPrefs(); 286 prefs_ = profile->GetPrefs();
216 287
217 // Listen for events to tell us when to load/unload persisted background 288 // Listen for events to tell us when to load/unload persisted background
218 // contents. 289 // contents.
219 StartObserving(profile); 290 StartObserving(profile);
220 } 291 }
221 292
222 BackgroundContentsService::~BackgroundContentsService() { 293 BackgroundContentsService::~BackgroundContentsService() {
223 // BackgroundContents should be shutdown before we go away, as otherwise 294 // BackgroundContents should be shutdown before we go away, as otherwise
224 // our browser process refcount will be off. 295 // our browser process refcount will be off.
225 DCHECK(contents_map_.empty()); 296 DCHECK(contents_map_.empty());
226 } 297 }
227 298
299 // static
300 void BackgroundContentsService::SetCrashDelaysForTesting(
301 const base::TimeDelta& restart_delay, const base::TimeDelta& crash_window) {
302 restart_delay_ = restart_delay;
303 crash_window_ = crash_window;
304 }
305
228 std::vector<BackgroundContents*> 306 std::vector<BackgroundContents*>
229 BackgroundContentsService::GetBackgroundContents() const 307 BackgroundContentsService::GetBackgroundContents() const
230 { 308 {
231 std::vector<BackgroundContents*> contents; 309 std::vector<BackgroundContents*> contents;
232 for (BackgroundContentsMap::const_iterator it = contents_map_.begin(); 310 for (BackgroundContentsMap::const_iterator it = contents_map_.begin();
233 it != contents_map_.end(); ++it) 311 it != contents_map_.end(); ++it)
234 contents.push_back(it->second.contents); 312 contents.push_back(it->second.contents);
235 return contents; 313 return contents;
236 } 314 }
237 315
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 if (service && service->is_ready()) { 420 if (service && service->is_ready()) {
343 // Now load the manifest-specified background page. If service isn't 421 // Now load the manifest-specified background page. If service isn't
344 // ready, then the background page will be loaded from the 422 // ready, then the background page will be loaded from the
345 // EXTENSIONS_READY callback. 423 // EXTENSIONS_READY callback.
346 LoadBackgroundContents(profile, 424 LoadBackgroundContents(profile,
347 BackgroundInfo::GetBackgroundURL(extension), 425 BackgroundInfo::GetBackgroundURL(extension),
348 ASCIIToUTF16("background"), 426 ASCIIToUTF16("background"),
349 UTF8ToUTF16(extension->id())); 427 UTF8ToUTF16(extension->id()));
350 } 428 }
351 } 429 }
352
353 // Remove any "This extension has crashed" balloons. 430 // Remove any "This extension has crashed" balloons.
354 ScheduleCloseBalloon(extension->id()); 431 ScheduleCloseCrashBalloon(extension->id());
355 SendChangeNotification(profile); 432 SendChangeNotification(profile);
356 break; 433 break;
357 } 434 }
358 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: 435 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED:
359 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED: { 436 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED: {
360 Profile* profile = content::Source<Profile>(source).ptr(); 437 Profile* profile = content::Source<Profile>(source).ptr();
361 const Extension* extension = NULL; 438 const Extension* extension = NULL;
362 if (type == chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED) { 439 if (type == chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED) {
363 BackgroundContents* bg = 440 BackgroundContents* bg =
364 content::Details<BackgroundContents>(details).ptr(); 441 content::Details<BackgroundContents>(details).ptr();
365 std::string extension_id = UTF16ToASCII( 442 std::string extension_id = UTF16ToASCII(
366 BackgroundContentsServiceFactory::GetForProfile(profile)-> 443 BackgroundContentsServiceFactory::GetForProfile(profile)->
367 GetParentApplicationId(bg)); 444 GetParentApplicationId(bg));
368 extension = 445 extension =
369 extensions::ExtensionSystem::Get(profile)->extension_service()-> 446 extensions::ExtensionSystem::Get(profile)->extension_service()->
370 GetExtensionById(extension_id, false); 447 GetExtensionById(extension_id, false);
371 } else { 448 } else {
372 extensions::ExtensionHost* extension_host = 449 extensions::ExtensionHost* extension_host =
373 content::Details<extensions::ExtensionHost>(details).ptr(); 450 content::Details<extensions::ExtensionHost>(details).ptr();
374 extension = extension_host->extension(); 451 extension = extension_host->extension();
375 } 452 }
376 if (!extension) 453 if (!extension)
377 break; 454 break;
378 455
379 // When an extension crashes, EXTENSION_PROCESS_TERMINATED is followed by 456 // When an extension crashes, EXTENSION_PROCESS_TERMINATED is followed by
380 // an EXTENSION_UNLOADED notification. This UNLOADED signal causes all the 457 // an EXTENSION_UNLOADED notification. We post the crash handling code as
bartfab (slow) 2013/08/26 13:26:53 The previous comment had more information on why p
anitawoodruff 2013/08/26 21:45:23 Done.
381 // notifications for this extension to be cancelled by 458 // a task here so it is not executed before the EXTENSION_UNLOADED event.
382 // DesktopNotificationService. For this reason, instead of showing the 459 bool forceInstalled =
383 // balloon right now, we schedule it to show a little later. 460 extension->location() ==
384 base::MessageLoop::current()->PostTask( 461 extensions::Manifest::EXTERNAL_POLICY_DOWNLOAD;
385 FROM_HERE, base::Bind(&ShowBalloon, extension, profile)); 462 if (!forceInstalled) {
463 // Notify user extension has crashed.
464 base::MessageLoop::current()->PostTask(
465 FROM_HERE, base::Bind(&ShowBalloon, extension, profile, false));
466 } else {
467 // Restart the extension; notify user if crash recurs frequently.
bartfab (slow) 2013/08/26 13:26:53 I think this code is complex enough to warrant put
anitawoodruff 2013/08/26 21:45:23 Done.
468 const std::string& id = extension->id();
bartfab (slow) 2013/08/26 13:26:53 Nit: Why not call the variable extension_id?
anitawoodruff 2013/08/26 21:45:23 Done.
469 const bool alreadyNotified =
470 misbehaving_extensions_.find(id) != misbehaving_extensions_.end();
471 std::queue<base::TimeTicks>& crashes = extension_crashlog_map_[id];
472 const base::TimeDelta duration =
473 kNCrashesShouldNotify * (restart_delay_ + crash_window_);
474 if (!alreadyNotified && crashes.size() == (kNCrashesShouldNotify - 1) &&
bartfab (slow) 2013/08/26 13:26:53 Please put the calculation on its own line and exp
anitawoodruff 2013/08/26 21:45:23 Done.
475 base::TimeTicks::Now() - crashes.front() < duration) {
476 base::MessageLoop::current()->PostTask(FROM_HERE,
477 base::Bind(&ShowBalloon, extension, profile, true));
478 misbehaving_extensions_.insert(id);
479 extension_crashlog_map_.erase(id);
480 } else if (!alreadyNotified) {
481 while (!crashes.empty() &&
482 base::TimeTicks::Now() - crashes.front() > duration) {
483 crashes.pop(); // Remove old timestamps.
484 }
485 crashes.push(base::TimeTicks::Now());
486 if (crashes.size() == kNCrashesShouldNotify)
487 crashes.pop();
488 }
489 base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
bartfab (slow) 2013/08/26 13:26:53 This task will run 3s later. What if |extension| o
anitawoodruff 2013/08/26 21:45:23 I traced it through to BrowserContextKeyedBaseFact
bartfab (slow) 2013/08/27 09:21:29 Sounds like both issues may arise - we may end up
490 base::Bind(&ReloadExtension, extension, profile), restart_delay_);
491 }
386 break; 492 break;
387 } 493 }
388 case chrome::NOTIFICATION_EXTENSION_UNLOADED: 494 case chrome::NOTIFICATION_EXTENSION_UNLOADED:
389 switch (content::Details<UnloadedExtensionInfo>(details)->reason) { 495 switch (content::Details<UnloadedExtensionInfo>(details)->reason) {
390 case extension_misc::UNLOAD_REASON_DISABLE: // Fall through. 496 case extension_misc::UNLOAD_REASON_DISABLE: // Fall through.
391 case extension_misc::UNLOAD_REASON_TERMINATE: // Fall through. 497 case extension_misc::UNLOAD_REASON_TERMINATE: // Fall through.
392 case extension_misc::UNLOAD_REASON_UNINSTALL: // Fall through. 498 case extension_misc::UNLOAD_REASON_UNINSTALL: // Fall through.
393 case extension_misc::UNLOAD_REASON_BLACKLIST: 499 case extension_misc::UNLOAD_REASON_BLACKLIST:
394 ShutdownAssociatedBackgroundContents( 500 ShutdownAssociatedBackgroundContents(
395 ASCIIToUTF16(content::Details<UnloadedExtensionInfo>(details)-> 501 ASCIIToUTF16(content::Details<UnloadedExtensionInfo>(details)->
(...skipping 16 matching lines...) Expand all
412 default: 518 default:
413 NOTREACHED(); 519 NOTREACHED();
414 ShutdownAssociatedBackgroundContents( 520 ShutdownAssociatedBackgroundContents(
415 ASCIIToUTF16(content::Details<UnloadedExtensionInfo>(details)-> 521 ASCIIToUTF16(content::Details<UnloadedExtensionInfo>(details)->
416 extension->id())); 522 extension->id()));
417 break; 523 break;
418 } 524 }
419 break; 525 break;
420 526
421 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: { 527 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
528 const std::string& extension_id =
529 content::Details<const Extension>(details).ptr()->id();
422 // Remove any "This extension has crashed" balloons. 530 // Remove any "This extension has crashed" balloons.
423 ScheduleCloseBalloon( 531 ScheduleCloseBalloons(extension_id);
424 content::Details<const Extension>(details).ptr()->id()); 532 misbehaving_extensions_.erase(extension_id);
533 extension_crashlog_map_.erase(extension_id);
425 break; 534 break;
426 } 535 }
427 536
428 default: 537 default:
429 NOTREACHED(); 538 NOTREACHED();
430 break; 539 break;
431 } 540 }
432 } 541 }
433 542
434 // Loads all background contents whose urls have been stored in prefs. 543 // Loads all background contents whose urls have been stored in prefs.
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 } 755 }
647 756
648 void BackgroundContentsService::BackgroundContentsOpened( 757 void BackgroundContentsService::BackgroundContentsOpened(
649 BackgroundContentsOpenedDetails* details) { 758 BackgroundContentsOpenedDetails* details) {
650 // Add the passed object to our list. Should not already be tracked. 759 // Add the passed object to our list. Should not already be tracked.
651 DCHECK(!IsTracked(details->contents)); 760 DCHECK(!IsTracked(details->contents));
652 DCHECK(!details->application_id.empty()); 761 DCHECK(!details->application_id.empty());
653 contents_map_[details->application_id].contents = details->contents; 762 contents_map_[details->application_id].contents = details->contents;
654 contents_map_[details->application_id].frame_name = details->frame_name; 763 contents_map_[details->application_id].frame_name = details->frame_name;
655 764
656 ScheduleCloseBalloon(UTF16ToASCII(details->application_id)); 765 ScheduleCloseBalloons(UTF16ToASCII(details->application_id));
bartfab (slow) 2013/08/26 13:26:53 Will this not close the "misbehaving app" balloon
anitawoodruff 2013/08/26 21:45:23 Done.
657 } 766 }
658 767
659 // Used by test code and debug checks to verify whether a given 768 // Used by test code and debug checks to verify whether a given
660 // BackgroundContents is being tracked by this instance. 769 // BackgroundContents is being tracked by this instance.
661 bool BackgroundContentsService::IsTracked( 770 bool BackgroundContentsService::IsTracked(
662 BackgroundContents* background_contents) const { 771 BackgroundContents* background_contents) const {
663 return !GetParentApplicationId(background_contents).empty(); 772 return !GetParentApplicationId(background_contents).empty();
664 } 773 }
665 774
666 void BackgroundContentsService::BackgroundContentsShutdown( 775 void BackgroundContentsService::BackgroundContentsShutdown(
(...skipping 27 matching lines...) Expand all
694 bool user_gesture, 803 bool user_gesture,
695 bool* was_blocked) { 804 bool* was_blocked) {
696 Browser* browser = chrome::FindLastActiveWithProfile( 805 Browser* browser = chrome::FindLastActiveWithProfile(
697 Profile::FromBrowserContext(new_contents->GetBrowserContext()), 806 Profile::FromBrowserContext(new_contents->GetBrowserContext()),
698 chrome::GetActiveDesktop()); 807 chrome::GetActiveDesktop());
699 if (browser) { 808 if (browser) {
700 chrome::AddWebContents(browser, NULL, new_contents, disposition, 809 chrome::AddWebContents(browser, NULL, new_contents, disposition,
701 initial_pos, user_gesture, was_blocked); 810 initial_pos, user_gesture, was_blocked);
702 } 811 }
703 } 812 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698