1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// 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;
// Gets and sets the preference for whether to put the component action with
// the given ID on the toolbar (or in the overflow menu).
// GetComponentActionPref() returns false if the pref has not been set.
bool GetComponentActionPref(const std::string& component_action_id) const;
void SetComponentActionPref(const std::string& component_action_id,
bool enabled);
protected:
// 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;
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_
|