15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/navigation_observer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_install_ui.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NavigationObserver::NavigationObserver(Profile* profile) : profile_(profile) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegisterForNotifications(); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NavigationObserver::~NavigationObserver() {} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NavigationObserver::Observe(int type, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type != content::NOTIFICATION_NAV_ENTRY_COMMITTED) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigationController* controller = 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<NavigationController>(source).ptr(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile_->IsSameProfile( 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(controller->GetBrowserContext()))) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PromptToEnableExtensionIfNecessary(controller); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NavigationObserver::RegisterForNotifications() { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllSources()); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NavigationObserver::PromptToEnableExtensionIfNecessary( 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigationController* nav_controller) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bail out if we're already running a prompt. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!in_progress_prompt_extension_id_.empty()) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NavigationEntry* nav_entry = nav_controller->GetVisibleEntry(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!nav_entry) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionRegistry* registry = extensions::ExtensionRegistry::Get(profile_); 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const Extension* extension = 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry->disabled_extensions().GetExtensionOrAppByURL( 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) nav_entry->GetURL()); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try not to repeatedly prompt the user about the same extension. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prompted_extensions_.find(extension->id()) != prompted_extensions_.end()) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prompted_extensions_.insert(extension->id()); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(profile_); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_prefs->DidExtensionEscalatePermissions(extension->id())) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keep track of the extension id and nav controller we're prompting for. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These must be reset in InstallUIProceed and InstallUIAbort. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_progress_prompt_extension_id_ = extension->id(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_progress_prompt_navigation_controller_ = nav_controller; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_install_prompt_.reset( 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ExtensionInstallPrompt(nav_controller->GetWebContents())); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_install_prompt_->ConfirmReEnable(this, extension); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NavigationObserver::InstallUIProceed() { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionService* extension_service = 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ExtensionSystem::Get(profile_)->extension_service(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = extension_service->GetExtensionById( 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_progress_prompt_extension_id_, true); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigationController* nav_controller = 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_progress_prompt_navigation_controller_; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(extension); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(nav_controller); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_progress_prompt_extension_id_ = ""; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_progress_prompt_navigation_controller_ = NULL; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_install_prompt_.reset(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Grant permissions, re-enable the extension, and then reload the tab. 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_service->GrantPermissionsAndEnableExtension(extension); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nav_controller->Reload(true); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NavigationObserver::InstallUIAbort(bool user_initiated) { 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionService* extension_service = 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ExtensionSystem::Get(profile_)->extension_service(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = extension_service->GetExtensionById( 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_progress_prompt_extension_id_, true); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_progress_prompt_extension_id_ = ""; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_progress_prompt_navigation_controller_ = NULL; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_install_prompt_.reset(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string histogram_name = user_initiated 11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ? "Extensions.Permissions_ReEnableCancel2" 11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : "Extensions.Permissions_ReEnableAbort2"; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionService::RecordPermissionMessagesHistogram( 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension, histogram_name.c_str()); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 123