| // Copyright 2016 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. |
| |
| #ifndef CHROME_BROWSER_EXTENSIONS_COMPONENT_MIGRATION_HELPER_H_ |
| #define CHROME_BROWSER_EXTENSIONS_COMPONENT_MIGRATION_HELPER_H_ |
| |
| #include <set> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/macros.h" |
| #include "base/scoped_observer.h" |
| #include "extensions/browser/extension_registry_observer.h" |
| |
| class Profile; |
| class PrefRegistrySimple; |
| class PrefService; |
| |
| namespace content { |
| class BrowserContext; |
| } |
| |
| namespace extensions { |
| |
| class ExtensionRegistry; |
| class ExtensionSystem; |
| |
| // For migrating existing extensions to component actions, and vice versa. A |
| // previous enabled extension is used as a signal to add the corresponding |
| // component action to the visible area of the toolbar. This allows users who |
| // have already installed the extension to have their preference for a component |
| // action in the visible area of the toolbar respected, without enabling this |
| // for the entire user base. |
| // |
| // MIGRATION LOGIC |
| // |
| // When the feature is enabled (i.e. by experiment or flag), the client should |
| // call OnFeatureEnabled(action_id). The extension action redesign MUST also be |
| // enabled. |
| // |
| // - If the extension is enabled, it is unloaded with a reason of |
| // MIGRATED_TO_COMPONENT, the component action shown, and a pref set |
| // recording the migration. |
| // - If pref is set the component action is shown. |
| // - Otherwise, the component action is not shown. |
| // |
| // When the feature is disabled (for example, by starting with a flag off), the |
| // client should call OnFeatureDisabled(action_id). |
| // |
| // - The pref is removed. |
| // - If the extension action redesign is enabled, the associated component |
| // action is removed. |
| // |
| // USAGE |
| // helper->Register("some-action-id", "some-extension-id"); |
| // helper->Register("some-action-id", "other-extension-id"); |
| // ... |
| // // When feature is enabled |
| // helper->OnFeatureEnabled("some-action-id"); |
| // ... |
| // // When feature is disabled |
| // helper->OnFeatureDisabled("some-action-id"); |
| // |
| // It is legal to register more than one extension per action but not vice |
| // versa. |
| class ComponentMigrationHelper : public ExtensionRegistryObserver { |
| public: |
| // Object that knows how to manage component actions in the toolbar model. |
| class ComponentActionDelegate { |
| public: |
| // Adds or removes the component action labeled by |action_id| from the |
| // toolbar model. The caller will not add the same action twice. |
| virtual void AddComponentAction(const std::string& action_id) = 0; |
| virtual void RemoveComponentAction(const std::string& action_id) = 0; |
| |
| // Returns |true| if the toolbar model has an action for |action_id|. |
| virtual bool HasComponentAction(const std::string& action_id) const = 0; |
| }; |
| |
| ComponentMigrationHelper(Profile* profile, ComponentActionDelegate* delegate); |
| ~ComponentMigrationHelper() override; |
| |
| static void RegisterPrefs(PrefRegistrySimple* registry); |
| |
| // Registers and unregisters a component action/extension pair. A component |
| // action may have more than one associated extension id, but not vice versa. |
| void Register(const std::string& component_action_id, |
| const ExtensionId& extension_id); |
| void Unregister(const std::string& component_action_id, |
| const ExtensionId& extension_id); |
| |
| // Call when we should potentially add the component action and unload |
| // the extension. PREREQUISITE: The extension action redesign MUST be |
| // enabled. |
| void OnFeatureEnabled(const std::string& component_action_id); |
| |
| // Call when we should potentially remove the component action and re-enable |
| // extension loading. |
| void OnFeatureDisabled(const std::string& component_action_id); |
| |
| // Call when the user manually removes the component action from the toolbar. |
| void OnActionRemoved(const std::string& component_action_id); |
| |
| // extensions::ExtensionRegistryObserver: |
| void OnExtensionReady(content::BrowserContext* browser_context, |
| const Extension* extension) override; |
| |
| protected: |
| // Protected for unit testing. |
| void SetComponentActionPref(const std::string& component_action_id, |
| bool enabled); |
| |
| // A set of component action ids whose features are currently enabled. |
| // Protected for unit testing. |
| std::set<std::string> enabled_actions_; |
| |
| private: |
| bool IsExtensionInstalledAndEnabled(const ExtensionId& extension_id) const; |
| void UnloadExtension(const ExtensionId& extension_id); |
| void RemoveComponentActionPref(const std::string& component_action_id); |
| std::vector<std::string> GetExtensionIdsForActionId( |
| const std::string& component_action_id) const; |
| std::string GetActionIdForExtensionId(const ExtensionId& extension_id) const; |
| |
| Profile* const profile_; |
| ComponentActionDelegate* const delegate_; |
| // The ExtensionRegistry, PrefService, and ExtensionSystem, cached for |
| // convenience. |
| ExtensionRegistry* const extension_registry_; |
| PrefService* const pref_service_; |
| ExtensionSystem* const extension_system_; |
| |
| ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> |
| extension_registry_observer_; |
| |
| // A list of pairs of component action ids and extension ids. |
| std::vector<std::pair<std::string, ExtensionId>> migrated_actions_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ComponentMigrationHelper); |
| }; |
| |
| } // namespace extensions |
| |
| #endif // CHROME_BROWSER_EXTENSIONS_COMPONENT_MIGRATION_HELPER_H_ |