// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/extensions/extension_action_test_util.h" #include "base/memory/scoped_ptr.h" #include "base/run_loop.h" #include "chrome/browser/extensions/extension_action.h" #include "chrome/browser/extensions/extension_action_manager.h" #include "chrome/browser/extensions/extension_toolbar_model.h" #include "chrome/browser/extensions/extension_toolbar_model_factory.h" #include "chrome/browser/extensions/location_bar_controller.h" #include "chrome/browser/extensions/tab_helper.h" #include "chrome/browser/extensions/test_extension_system.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/session_tab_helper.h" #include "components/crx_file/id_util.h" #include "content/public/browser/web_contents.h" #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" #include "extensions/common/feature_switch.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/value_builder.h" namespace extensions { namespace extension_action_test_util { namespace { size_t GetPageActionCount(content::WebContents* web_contents, bool only_count_visible) { DCHECK(web_contents); size_t count = 0u; int tab_id = SessionTabHelper::IdForTab(web_contents); // Page actions are either stored in the location bar (and provided by the // LocationBarController), or in the main toolbar (and provided by the // ExtensionToolbarModel), depending on whether or not the extension action // redesign is enabled. if (!FeatureSwitch::extension_action_redesign()->IsEnabled()) { std::vector page_actions = TabHelper::FromWebContents(web_contents)-> location_bar_controller()->GetCurrentActions(); count = page_actions.size(); // Trim any invisible page actions, if necessary. if (only_count_visible) { for (std::vector::iterator iter = page_actions.begin(); iter != page_actions.end(); ++iter) { if (!(*iter)->GetIsVisible(tab_id)) --count; } } } else { ExtensionToolbarModel* toolbar_model = ExtensionToolbarModel::Get( Profile::FromBrowserContext(web_contents->GetBrowserContext())); const ExtensionList& toolbar_extensions = toolbar_model->toolbar_items(); ExtensionActionManager* action_manager = ExtensionActionManager::Get(web_contents->GetBrowserContext()); for (ExtensionList::const_iterator iter = toolbar_extensions.begin(); iter != toolbar_extensions.end(); ++iter) { ExtensionAction* extension_action = action_manager->GetPageAction(**iter); if (extension_action && (!only_count_visible || extension_action->GetIsVisible(tab_id))) ++count; } } return count; } // Creates a new ExtensionToolbarModel for the given |context|. scoped_ptr BuildToolbarModel(content::BrowserContext* context) { return make_scoped_ptr(new extensions::ExtensionToolbarModel( Profile::FromBrowserContext(context), extensions::ExtensionPrefs::Get(context))); } // Creates a new ExtensionToolbarModel for the given profile, optionally // triggering the extension system's ready signal. ExtensionToolbarModel* CreateToolbarModelImpl(Profile* profile, bool wait_for_ready) { ExtensionToolbarModel* model = ExtensionToolbarModel::Get(profile); if (model) return model; // No existing model means it's a new profile (since we, by default, don't // create the ToolbarModel in testing). ExtensionToolbarModelFactory::GetInstance()->SetTestingFactory( profile, &BuildToolbarModel); model = ExtensionToolbarModel::Get(profile); if (wait_for_ready) { // Fake the extension system ready signal. // HACK ALERT! In production, the ready task on ExtensionSystem (and most // everything else on it, too) is shared between incognito and normal // profiles, but a TestExtensionSystem doesn't have the concept of "shared". // Because of this, we have to set any new profile's TestExtensionSystem's // ready task, too. static_cast(ExtensionSystem::Get(profile))-> SetReady(); // Run tasks posted to TestExtensionSystem. base::RunLoop().RunUntilIdle(); } return model; } } // namespace size_t GetVisiblePageActionCount(content::WebContents* web_contents) { return GetPageActionCount(web_contents, true); } size_t GetTotalPageActionCount(content::WebContents* web_contents) { return GetPageActionCount(web_contents, false); } scoped_refptr CreateActionExtension(const std::string& name, ActionType action_type) { return CreateActionExtension(name, action_type, Manifest::INTERNAL); } scoped_refptr CreateActionExtension( const std::string& name, ActionType action_type, Manifest::Location location) { DictionaryBuilder manifest; manifest.Set("name", name) .Set("description", "An extension") .Set("manifest_version", 2) .Set("version", "1.0.0"); const char* action_key = nullptr; switch (action_type) { case NO_ACTION: break; case PAGE_ACTION: action_key = manifest_keys::kPageAction; break; case BROWSER_ACTION: action_key = manifest_keys::kBrowserAction; break; } if (action_key) manifest.Set(action_key, DictionaryBuilder().Pass()); return ExtensionBuilder().SetManifest(manifest.Pass()). SetID(crx_file::id_util::GenerateId(name)). SetLocation(location). Build(); } ExtensionToolbarModel* CreateToolbarModelForProfile(Profile* profile) { return CreateToolbarModelImpl(profile, true); } ExtensionToolbarModel* CreateToolbarModelForProfileWithoutWaitingForReady( Profile* profile) { return CreateToolbarModelImpl(profile, false); } } // namespace extension_action_test_util } // namespace extensions