| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/ui/views/extensions/extension_message_bubble_view.h" | 5 #include "chrome/browser/ui/views/extensions/extension_message_bubble_view.h" |
| 6 | 6 |
| 7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "chrome/browser/extensions/dev_mode_bubble_controller.h" | 10 #include "chrome/browser/extensions/dev_mode_bubble_controller.h" |
| 11 #include "chrome/browser/extensions/extension_action_manager.h" | 11 #include "chrome/browser/extensions/extension_action_manager.h" |
| 12 #include "chrome/browser/extensions/extension_message_bubble_controller.h" | 12 #include "chrome/browser/extensions/extension_message_bubble_controller.h" |
| 13 #include "chrome/browser/extensions/extension_service.h" | 13 #include "chrome/browser/extensions/extension_service.h" |
| 14 #include "chrome/browser/extensions/proxy_overridden_bubble_controller.h" | |
| 15 #include "chrome/browser/extensions/settings_api_bubble_controller.h" | 14 #include "chrome/browser/extensions/settings_api_bubble_controller.h" |
| 16 #include "chrome/browser/extensions/settings_api_helpers.h" | 15 #include "chrome/browser/extensions/settings_api_helpers.h" |
| 17 #include "chrome/browser/extensions/suspicious_extension_bubble_controller.h" | 16 #include "chrome/browser/extensions/suspicious_extension_bubble_controller.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/ui/view_ids.h" | |
| 20 #include "chrome/browser/ui/views/frame/browser_view.h" | 18 #include "chrome/browser/ui/views/frame/browser_view.h" |
| 21 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" | 19 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" |
| 22 #include "chrome/browser/ui/views/toolbar/browser_actions_container_observer.h" | 20 #include "chrome/browser/ui/views/toolbar/browser_actions_container_observer.h" |
| 23 #include "chrome/browser/ui/views/toolbar/toolbar_view.h" | 21 #include "chrome/browser/ui/views/toolbar/toolbar_view.h" |
| 24 #include "extensions/browser/extension_prefs.h" | 22 #include "extensions/browser/extension_prefs.h" |
| 25 #include "extensions/browser/extension_system.h" | 23 #include "extensions/browser/extension_system.h" |
| 26 #include "grit/locale_settings.h" | 24 #include "grit/locale_settings.h" |
| 27 #include "ui/accessibility/ax_view_state.h" | 25 #include "ui/accessibility/ax_view_state.h" |
| 28 #include "ui/base/resource/resource_bundle.h" | 26 #include "ui/base/resource/resource_bundle.h" |
| 29 #include "ui/views/controls/button/label_button.h" | 27 #include "ui/views/controls/button/label_button.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 57 | 55 |
| 58 namespace extensions { | 56 namespace extensions { |
| 59 | 57 |
| 60 ExtensionMessageBubbleView::ExtensionMessageBubbleView( | 58 ExtensionMessageBubbleView::ExtensionMessageBubbleView( |
| 61 views::View* anchor_view, | 59 views::View* anchor_view, |
| 62 views::BubbleBorder::Arrow arrow_location, | 60 views::BubbleBorder::Arrow arrow_location, |
| 63 scoped_ptr<extensions::ExtensionMessageBubbleController> controller) | 61 scoped_ptr<extensions::ExtensionMessageBubbleController> controller) |
| 64 : BubbleDelegateView(anchor_view, arrow_location), | 62 : BubbleDelegateView(anchor_view, arrow_location), |
| 65 weak_factory_(this), | 63 weak_factory_(this), |
| 66 controller_(controller.Pass()), | 64 controller_(controller.Pass()), |
| 67 anchor_view_(anchor_view), | |
| 68 headline_(NULL), | 65 headline_(NULL), |
| 69 learn_more_(NULL), | 66 learn_more_(NULL), |
| 70 dismiss_button_(NULL), | 67 dismiss_button_(NULL), |
| 71 link_clicked_(false), | 68 link_clicked_(false), |
| 72 action_taken_(false) { | 69 action_taken_(false) { |
| 73 DCHECK(anchor_view->GetWidget()); | 70 DCHECK(anchor_view->GetWidget()); |
| 74 set_close_on_deactivate(controller_->CloseOnDeactivate()); | 71 set_close_on_deactivate(controller_->CloseOnDeactivate()); |
| 75 set_close_on_esc(true); | 72 set_close_on_esc(true); |
| 76 | 73 |
| 77 // Compensate for built-in vertical padding in the anchor view's image. | 74 // Compensate for built-in vertical padding in the anchor view's image. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 const int text_column_set_id = 1; | 149 const int text_column_set_id = 1; |
| 153 views::ColumnSet* upper_columns = layout->AddColumnSet(text_column_set_id); | 150 views::ColumnSet* upper_columns = layout->AddColumnSet(text_column_set_id); |
| 154 upper_columns->AddColumn( | 151 upper_columns->AddColumn( |
| 155 views::GridLayout::LEADING, views::GridLayout::LEADING, | 152 views::GridLayout::LEADING, views::GridLayout::LEADING, |
| 156 0, views::GridLayout::USE_PREF, 0, 0); | 153 0, views::GridLayout::USE_PREF, 0, 0); |
| 157 layout->StartRow(0, text_column_set_id); | 154 layout->StartRow(0, text_column_set_id); |
| 158 | 155 |
| 159 views::Label* message = new views::Label(); | 156 views::Label* message = new views::Label(); |
| 160 message->SetMultiLine(true); | 157 message->SetMultiLine(true); |
| 161 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 158 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 162 message->SetText(delegate->GetMessageBody( | 159 message->SetText(delegate->GetMessageBody()); |
| 163 anchor_view_->id() == VIEW_ID_BROWSER_ACTION)); | |
| 164 message->SizeToFit(views::Widget::GetLocalizedContentsWidth( | 160 message->SizeToFit(views::Widget::GetLocalizedContentsWidth( |
| 165 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); | 161 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); |
| 166 layout->AddView(message); | 162 layout->AddView(message); |
| 167 | 163 |
| 168 if (delegate->ShouldShowExtensionList()) { | 164 if (delegate->ShouldShowExtensionList()) { |
| 169 const int extension_list_column_set_id = 2; | 165 const int extension_list_column_set_id = 2; |
| 170 views::ColumnSet* middle_columns = | 166 views::ColumnSet* middle_columns = |
| 171 layout->AddColumnSet(extension_list_column_set_id); | 167 layout->AddColumnSet(extension_list_column_set_id); |
| 172 middle_columns->AddPaddingColumn(0, kExtensionListPadding); | 168 middle_columns->AddPaddingColumn(0, kExtensionListPadding); |
| 173 middle_columns->AddColumn( | 169 middle_columns->AddColumn( |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 //////////////////////////////////////////////////////////////////////////////// | 265 //////////////////////////////////////////////////////////////////////////////// |
| 270 // ExtensionMessageBubbleFactory | 266 // ExtensionMessageBubbleFactory |
| 271 | 267 |
| 272 ExtensionMessageBubbleFactory::ExtensionMessageBubbleFactory( | 268 ExtensionMessageBubbleFactory::ExtensionMessageBubbleFactory( |
| 273 Profile* profile, | 269 Profile* profile, |
| 274 ToolbarView* toolbar_view) | 270 ToolbarView* toolbar_view) |
| 275 : profile_(profile), | 271 : profile_(profile), |
| 276 toolbar_view_(toolbar_view), | 272 toolbar_view_(toolbar_view), |
| 277 shown_suspicious_extensions_bubble_(false), | 273 shown_suspicious_extensions_bubble_(false), |
| 278 shown_startup_override_extensions_bubble_(false), | 274 shown_startup_override_extensions_bubble_(false), |
| 279 shown_proxy_override_extensions_bubble_(false), | |
| 280 shown_dev_mode_extensions_bubble_(false), | 275 shown_dev_mode_extensions_bubble_(false), |
| 281 is_observing_(false), | 276 is_observing_(false), |
| 282 stage_(STAGE_START), | 277 stage_(STAGE_START), |
| 283 container_(NULL), | 278 container_(NULL), |
| 284 anchor_view_(NULL) {} | 279 anchor_view_(NULL) {} |
| 285 | 280 |
| 286 ExtensionMessageBubbleFactory::~ExtensionMessageBubbleFactory() { | 281 ExtensionMessageBubbleFactory::~ExtensionMessageBubbleFactory() { |
| 287 MaybeStopObserving(); | 282 MaybeStopObserving(); |
| 288 } | 283 } |
| 289 | 284 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 302 // way, we're not too spammy with the bubbles. | 297 // way, we're not too spammy with the bubbles. |
| 303 if (!shown_suspicious_extensions_bubble_ && | 298 if (!shown_suspicious_extensions_bubble_ && |
| 304 MaybeShowSuspiciousExtensionsBubble(anchor_view)) | 299 MaybeShowSuspiciousExtensionsBubble(anchor_view)) |
| 305 return; | 300 return; |
| 306 | 301 |
| 307 if (!shown_startup_override_extensions_bubble_ && | 302 if (!shown_startup_override_extensions_bubble_ && |
| 308 is_initial_check && | 303 is_initial_check && |
| 309 MaybeShowStartupOverrideExtensionsBubble(anchor_view)) | 304 MaybeShowStartupOverrideExtensionsBubble(anchor_view)) |
| 310 return; | 305 return; |
| 311 | 306 |
| 312 if (!shown_proxy_override_extensions_bubble_ && | |
| 313 MaybeShowProxyOverrideExtensionsBubble(anchor_view)) | |
| 314 return; | |
| 315 | |
| 316 if (!shown_dev_mode_extensions_bubble_) | 307 if (!shown_dev_mode_extensions_bubble_) |
| 317 MaybeShowDevModeExtensionsBubble(anchor_view); | 308 MaybeShowDevModeExtensionsBubble(anchor_view); |
| 318 #endif // OS_WIN | 309 #endif // OS_WIN |
| 319 } | 310 } |
| 320 | 311 |
| 321 bool ExtensionMessageBubbleFactory::MaybeShowSuspiciousExtensionsBubble( | 312 bool ExtensionMessageBubbleFactory::MaybeShowSuspiciousExtensionsBubble( |
| 322 views::View* anchor_view) { | 313 views::View* anchor_view) { |
| 323 DCHECK(!shown_suspicious_extensions_bubble_); | 314 DCHECK(!shown_suspicious_extensions_bubble_); |
| 324 | 315 |
| 325 scoped_ptr<SuspiciousExtensionBubbleController> suspicious_extensions( | 316 scoped_ptr<SuspiciousExtensionBubbleController> suspicious_extensions( |
| (...skipping 12 matching lines...) Expand all Loading... |
| 338 views::BubbleDelegateView::CreateBubble(bubble_delegate); | 329 views::BubbleDelegateView::CreateBubble(bubble_delegate); |
| 339 weak_controller->Show(bubble_delegate); | 330 weak_controller->Show(bubble_delegate); |
| 340 | 331 |
| 341 return true; | 332 return true; |
| 342 } | 333 } |
| 343 | 334 |
| 344 bool ExtensionMessageBubbleFactory::MaybeShowStartupOverrideExtensionsBubble( | 335 bool ExtensionMessageBubbleFactory::MaybeShowStartupOverrideExtensionsBubble( |
| 345 views::View* anchor_view) { | 336 views::View* anchor_view) { |
| 346 #if !defined(OS_WIN) | 337 #if !defined(OS_WIN) |
| 347 return false; | 338 return false; |
| 348 #else | 339 #endif |
| 340 |
| 349 DCHECK(!shown_startup_override_extensions_bubble_); | 341 DCHECK(!shown_startup_override_extensions_bubble_); |
| 350 | 342 |
| 351 const Extension* extension = | 343 const Extension* extension = OverridesStartupPages(profile_, NULL); |
| 352 GetExtensionOverridingStartupPages(profile_, NULL); | |
| 353 if (!extension) | 344 if (!extension) |
| 354 return false; | 345 return false; |
| 355 | 346 |
| 356 scoped_ptr<SettingsApiBubbleController> settings_api_bubble( | 347 scoped_ptr<SettingsApiBubbleController> settings_api_bubble( |
| 357 new SettingsApiBubbleController(profile_, | 348 new SettingsApiBubbleController(profile_, |
| 358 BUBBLE_TYPE_STARTUP_PAGES)); | 349 BUBBLE_TYPE_STARTUP_PAGES)); |
| 359 if (!settings_api_bubble->ShouldShow(extension->id())) | 350 if (!settings_api_bubble->ShouldShow(extension->id())) |
| 360 return false; | 351 return false; |
| 361 | 352 |
| 362 shown_startup_override_extensions_bubble_ = true; | 353 shown_startup_override_extensions_bubble_ = true; |
| 363 PrepareToHighlightExtensions( | 354 SettingsApiBubbleController* weak_controller = settings_api_bubble.get(); |
| 364 settings_api_bubble.PassAs<ExtensionMessageBubbleController>(), | 355 ExtensionMessageBubbleView* bubble_delegate = new ExtensionMessageBubbleView( |
| 365 anchor_view); | 356 anchor_view, |
| 357 views::BubbleBorder::TOP_RIGHT, |
| 358 settings_api_bubble.PassAs<ExtensionMessageBubbleController>()); |
| 359 views::BubbleDelegateView::CreateBubble(bubble_delegate); |
| 360 weak_controller->Show(bubble_delegate); |
| 361 |
| 366 return true; | 362 return true; |
| 367 #endif | |
| 368 } | |
| 369 | |
| 370 bool ExtensionMessageBubbleFactory::MaybeShowProxyOverrideExtensionsBubble( | |
| 371 views::View* anchor_view) { | |
| 372 #if !defined(OS_WIN) | |
| 373 return false; | |
| 374 #else | |
| 375 DCHECK(!shown_proxy_override_extensions_bubble_); | |
| 376 | |
| 377 const Extension* extension = GetExtensionOverridingProxy(profile_); | |
| 378 if (!extension) | |
| 379 return false; | |
| 380 | |
| 381 scoped_ptr<ProxyOverriddenBubbleController> proxy_bubble( | |
| 382 new ProxyOverriddenBubbleController(profile_)); | |
| 383 if (!proxy_bubble->ShouldShow(extension->id())) | |
| 384 return false; | |
| 385 | |
| 386 shown_proxy_override_extensions_bubble_ = true; | |
| 387 PrepareToHighlightExtensions( | |
| 388 proxy_bubble.PassAs<ExtensionMessageBubbleController>(), anchor_view); | |
| 389 return true; | |
| 390 #endif | |
| 391 } | 363 } |
| 392 | 364 |
| 393 bool ExtensionMessageBubbleFactory::MaybeShowDevModeExtensionsBubble( | 365 bool ExtensionMessageBubbleFactory::MaybeShowDevModeExtensionsBubble( |
| 394 views::View* anchor_view) { | 366 views::View* anchor_view) { |
| 395 DCHECK(!shown_dev_mode_extensions_bubble_); | 367 DCHECK(!shown_dev_mode_extensions_bubble_); |
| 396 | 368 |
| 397 // Check the Developer Mode extensions. | 369 // Check the Developer Mode extensions. |
| 398 scoped_ptr<DevModeBubbleController> dev_mode_extensions( | 370 scoped_ptr<DevModeBubbleController> dev_mode_extensions( |
| 399 new DevModeBubbleController(profile_)); | 371 new DevModeBubbleController(profile_)); |
| 400 | 372 |
| 401 // Return early if we have none to show. | 373 // Return early if we have none to show. |
| 402 if (!dev_mode_extensions->ShouldShow()) | 374 if (!dev_mode_extensions->ShouldShow()) |
| 403 return false; | 375 return false; |
| 404 | 376 |
| 405 shown_dev_mode_extensions_bubble_ = true; | 377 shown_dev_mode_extensions_bubble_ = true; |
| 406 PrepareToHighlightExtensions( | 378 |
| 407 dev_mode_extensions.PassAs<ExtensionMessageBubbleController>(), | 379 // We should be in the start stage (i.e., should not have a pending attempt to |
| 408 anchor_view); | 380 // show a bubble). |
| 381 DCHECK_EQ(stage_, STAGE_START); |
| 382 |
| 383 // Prepare to display and highlight the developer mode extensions before |
| 384 // showing the bubble. Since this is an asynchronous process, set member |
| 385 // variables for later use. |
| 386 controller_ = dev_mode_extensions.Pass(); |
| 387 anchor_view_ = anchor_view; |
| 388 container_ = toolbar_view_->browser_actions(); |
| 389 |
| 390 if (container_->animating()) |
| 391 MaybeObserve(); |
| 392 else |
| 393 HighlightDevModeExtensions(); |
| 394 |
| 409 return true; | 395 return true; |
| 410 } | 396 } |
| 411 | 397 |
| 412 void ExtensionMessageBubbleFactory::MaybeObserve() { | 398 void ExtensionMessageBubbleFactory::MaybeObserve() { |
| 413 if (!is_observing_) { | 399 if (!is_observing_) { |
| 414 is_observing_ = true; | 400 is_observing_ = true; |
| 415 container_->AddObserver(this); | 401 container_->AddObserver(this); |
| 416 } | 402 } |
| 417 } | 403 } |
| 418 | 404 |
| 419 void ExtensionMessageBubbleFactory::MaybeStopObserving() { | 405 void ExtensionMessageBubbleFactory::MaybeStopObserving() { |
| 420 if (is_observing_) { | 406 if (is_observing_) { |
| 421 is_observing_ = false; | 407 is_observing_ = false; |
| 422 container_->RemoveObserver(this); | 408 container_->RemoveObserver(this); |
| 423 } | 409 } |
| 424 } | 410 } |
| 425 | 411 |
| 426 void ExtensionMessageBubbleFactory::RecordProfileCheck(Profile* profile) { | 412 void ExtensionMessageBubbleFactory::RecordProfileCheck(Profile* profile) { |
| 427 g_profiles_evaluated.Get().insert(profile); | 413 g_profiles_evaluated.Get().insert(profile); |
| 428 } | 414 } |
| 429 | 415 |
| 430 bool ExtensionMessageBubbleFactory::IsInitialProfileCheck(Profile* profile) { | 416 bool ExtensionMessageBubbleFactory::IsInitialProfileCheck(Profile* profile) { |
| 431 return g_profiles_evaluated.Get().count(profile) == 0; | 417 return g_profiles_evaluated.Get().count(profile) == 0; |
| 432 } | 418 } |
| 433 | 419 |
| 434 void ExtensionMessageBubbleFactory::OnBrowserActionsContainerAnimationEnded() { | 420 void ExtensionMessageBubbleFactory::OnBrowserActionsContainerAnimationEnded() { |
| 435 MaybeStopObserving(); | 421 MaybeStopObserving(); |
| 436 if (stage_ == STAGE_START) { | 422 if (stage_ == STAGE_START) { |
| 437 HighlightExtensions(); | 423 HighlightDevModeExtensions(); |
| 438 } else if (stage_ == STAGE_HIGHLIGHTED) { | 424 } else if (stage_ == STAGE_HIGHLIGHTED) { |
| 439 ShowHighlightingBubble(); | 425 ShowDevModeBubble(); |
| 440 } else { // We shouldn't be observing if we've completed the process. | 426 } else { // We shouldn't be observing if we've completed the process. |
| 441 NOTREACHED(); | 427 NOTREACHED(); |
| 442 Finish(); | 428 Finish(); |
| 443 } | 429 } |
| 444 } | 430 } |
| 445 | 431 |
| 446 void ExtensionMessageBubbleFactory::OnBrowserActionsContainerDestroyed() { | 432 void ExtensionMessageBubbleFactory::OnBrowserActionsContainerDestroyed() { |
| 447 // If the container associated with the bubble is destroyed, abandon the | 433 // If the container associated with the bubble is destroyed, abandon the |
| 448 // process. | 434 // process. |
| 449 Finish(); | 435 Finish(); |
| 450 } | 436 } |
| 451 | 437 |
| 452 void ExtensionMessageBubbleFactory::PrepareToHighlightExtensions( | 438 void ExtensionMessageBubbleFactory::HighlightDevModeExtensions() { |
| 453 scoped_ptr<ExtensionMessageBubbleController> controller, | |
| 454 views::View* anchor_view) { | |
| 455 // We should be in the start stage (i.e., should not have a pending attempt to | |
| 456 // show a bubble). | |
| 457 DCHECK_EQ(stage_, STAGE_START); | |
| 458 | |
| 459 // Prepare to display and highlight the extensions before showing the bubble. | |
| 460 // Since this is an asynchronous process, set member variables for later use. | |
| 461 controller_ = controller.Pass(); | |
| 462 anchor_view_ = anchor_view; | |
| 463 container_ = toolbar_view_->browser_actions(); | |
| 464 | |
| 465 if (container_->animating()) | |
| 466 MaybeObserve(); | |
| 467 else | |
| 468 HighlightExtensions(); | |
| 469 } | |
| 470 | |
| 471 void ExtensionMessageBubbleFactory::HighlightExtensions() { | |
| 472 DCHECK_EQ(STAGE_START, stage_); | 439 DCHECK_EQ(STAGE_START, stage_); |
| 473 stage_ = STAGE_HIGHLIGHTED; | 440 stage_ = STAGE_HIGHLIGHTED; |
| 474 | 441 |
| 475 const ExtensionIdList extension_list = controller_->GetExtensionIdList(); | 442 const ExtensionIdList extension_list = controller_->GetExtensionIdList(); |
| 476 DCHECK(!extension_list.empty()); | 443 DCHECK(!extension_list.empty()); |
| 477 ExtensionToolbarModel::Get(profile_)->HighlightExtensions(extension_list); | 444 ExtensionToolbarModel::Get(profile_)->HighlightExtensions(extension_list); |
| 478 if (container_->animating()) | 445 if (container_->animating()) |
| 479 MaybeObserve(); | 446 MaybeObserve(); |
| 480 else | 447 else |
| 481 ShowHighlightingBubble(); | 448 ShowDevModeBubble(); |
| 482 } | 449 } |
| 483 | 450 |
| 484 void ExtensionMessageBubbleFactory::ShowHighlightingBubble() { | 451 void ExtensionMessageBubbleFactory::ShowDevModeBubble() { |
| 485 DCHECK_EQ(stage_, STAGE_HIGHLIGHTED); | 452 DCHECK_EQ(stage_, STAGE_HIGHLIGHTED); |
| 486 stage_ = STAGE_COMPLETE; | 453 stage_ = STAGE_COMPLETE; |
| 487 | 454 |
| 488 views::View* reference_view = NULL; | 455 views::View* reference_view = NULL; |
| 489 if (container_->num_browser_actions() > 0) | 456 if (container_->num_browser_actions() > 0) |
| 490 reference_view = container_->GetBrowserActionViewAt(0); | 457 reference_view = container_->GetBrowserActionViewAt(0); |
| 491 if (reference_view && reference_view->visible()) | 458 if (reference_view && reference_view->visible()) |
| 492 anchor_view_ = reference_view; | 459 anchor_view_ = reference_view; |
| 493 | 460 |
| 494 ExtensionMessageBubbleController* weak_controller = controller_.get(); | 461 DevModeBubbleController* weak_controller = controller_.get(); |
| 495 ExtensionMessageBubbleView* bubble_delegate = | 462 ExtensionMessageBubbleView* bubble_delegate = new ExtensionMessageBubbleView( |
| 496 new ExtensionMessageBubbleView( | 463 anchor_view_, |
| 497 anchor_view_, | 464 views::BubbleBorder::TOP_RIGHT, |
| 498 views::BubbleBorder::TOP_RIGHT, | 465 scoped_ptr<ExtensionMessageBubbleController>(controller_.release())); |
| 499 scoped_ptr<ExtensionMessageBubbleController>( | |
| 500 controller_.release())); | |
| 501 views::BubbleDelegateView::CreateBubble(bubble_delegate); | 466 views::BubbleDelegateView::CreateBubble(bubble_delegate); |
| 502 weak_controller->Show(bubble_delegate); | 467 weak_controller->Show(bubble_delegate); |
| 503 | 468 |
| 504 Finish(); | 469 Finish(); |
| 505 } | 470 } |
| 506 | 471 |
| 507 void ExtensionMessageBubbleFactory::Finish() { | 472 void ExtensionMessageBubbleFactory::Finish() { |
| 508 MaybeStopObserving(); | 473 MaybeStopObserving(); |
| 509 controller_.reset(); | 474 controller_.reset(); |
| 510 anchor_view_ = NULL; | 475 anchor_view_ = NULL; |
| 511 container_ = NULL; | 476 container_ = NULL; |
| 512 } | 477 } |
| 513 | 478 |
| 514 } // namespace extensions | 479 } // namespace extensions |
| OLD | NEW |