| Index: chrome/browser/extensions/api/developer_private/developer_private_api.cc
|
| diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
|
| index 47e5e9383f54a7240a4a2a622bef60c65fcebef3..6456612e6097af90c72b644c8180df7f994c961b 100644
|
| --- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
|
| +++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
|
| @@ -4,7 +4,6 @@
|
|
|
| #include "chrome/browser/extensions/api/developer_private/developer_private_api.h"
|
|
|
| -#include "base/base64.h"
|
| #include "base/bind.h"
|
| #include "base/files/file_util.h"
|
| #include "base/lazy_instance.h"
|
| @@ -61,12 +60,10 @@
|
| #include "extensions/browser/notification_types.h"
|
| #include "extensions/browser/warning_service.h"
|
| #include "extensions/common/constants.h"
|
| -#include "extensions/common/extension_resource.h"
|
| #include "extensions/common/extension_set.h"
|
| #include "extensions/common/feature_switch.h"
|
| #include "extensions/common/install_warning.h"
|
| #include "extensions/common/manifest.h"
|
| -#include "extensions/common/manifest_handlers/icons_handler.h"
|
| #include "extensions/common/manifest_handlers/options_page_info.h"
|
| #include "extensions/common/permissions/permissions_data.h"
|
| #include "extensions/grit/extensions_browser_resources.h"
|
| @@ -76,11 +73,10 @@
|
| #include "storage/browser/fileapi/file_system_operation_runner.h"
|
| #include "storage/browser/fileapi/isolated_context.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
| -#include "ui/base/resource/resource_bundle.h"
|
|
|
| namespace extensions {
|
|
|
| -namespace developer_private = api::developer_private;
|
| +namespace developer = api::developer_private;
|
|
|
| namespace {
|
|
|
| @@ -111,60 +107,6 @@ ExtensionService* GetExtensionService(content::BrowserContext* context) {
|
| return ExtensionSystem::Get(context)->extension_service();
|
| }
|
|
|
| -GURL GetImageURLFromData(const std::string& contents) {
|
| - std::string contents_base64;
|
| - base::Base64Encode(contents, &contents_base64);
|
| -
|
| - // TODO(dvh): make use of content::kDataScheme. Filed as crbug/297301.
|
| - const char kDataURLPrefix[] = "data:;base64,";
|
| - return GURL(kDataURLPrefix + contents_base64);
|
| -}
|
| -
|
| -GURL GetDefaultImageURL(developer_private::ItemType type) {
|
| - int icon_resource_id;
|
| - switch (type) {
|
| - case developer::ITEM_TYPE_LEGACY_PACKAGED_APP:
|
| - case developer::ITEM_TYPE_HOSTED_APP:
|
| - case developer::ITEM_TYPE_PACKAGED_APP:
|
| - icon_resource_id = IDR_APP_DEFAULT_ICON;
|
| - break;
|
| - default:
|
| - icon_resource_id = IDR_EXTENSION_DEFAULT_ICON;
|
| - break;
|
| - }
|
| -
|
| - return GetImageURLFromData(
|
| - ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
|
| - icon_resource_id, ui::SCALE_FACTOR_100P).as_string());
|
| -}
|
| -
|
| -// TODO(dvh): This code should be refactored and moved to
|
| -// extensions::ImageLoader. Also a resize should be performed to avoid
|
| -// potential huge URLs: crbug/297298.
|
| -GURL ToDataURL(const base::FilePath& path, developer_private::ItemType type) {
|
| - std::string contents;
|
| - if (path.empty() || !base::ReadFileToString(path, &contents))
|
| - return GetDefaultImageURL(type);
|
| -
|
| - return GetImageURLFromData(contents);
|
| -}
|
| -
|
| -void BroadcastItemStateChanged(content::BrowserContext* browser_context,
|
| - developer::EventType event_type,
|
| - const std::string& item_id) {
|
| - developer::EventData event_data;
|
| - event_data.event_type = event_type;
|
| - event_data.item_id = item_id;
|
| - event_data.extension_info =
|
| - ExtensionInfoGenerator(browser_context).CreateExtensionInfo(item_id);
|
| -
|
| - scoped_ptr<base::ListValue> args(new base::ListValue());
|
| - args->Append(event_data.ToValue().release());
|
| - scoped_ptr<Event> event(new Event(
|
| - developer_private::OnItemStateChanged::kEventName, args.Pass()));
|
| - EventRouter::Get(browser_context)->BroadcastEvent(event.Pass());
|
| -}
|
| -
|
| std::string ReadFileToString(const base::FilePath& path) {
|
| std::string data;
|
| ignore_result(base::ReadFileToString(path, &data));
|
| @@ -246,7 +188,9 @@ DeveloperPrivateEventRouter::DeveloperPrivateEventRouter(Profile* profile)
|
| process_manager_observer_(this),
|
| app_window_registry_observer_(this),
|
| extension_action_api_observer_(this),
|
| - profile_(profile) {
|
| + profile_(profile),
|
| + event_router_(EventRouter::Get(profile_)),
|
| + weak_factory_(this) {
|
| extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
|
| error_console_observer_.Add(ErrorConsole::Get(profile));
|
| process_manager_observer_.Add(ProcessManager::Get(profile));
|
| @@ -271,8 +215,7 @@ void DeveloperPrivateEventRouter::OnExtensionLoaded(
|
| content::BrowserContext* browser_context,
|
| const Extension* extension) {
|
| DCHECK(profile_->IsSameProfile(Profile::FromBrowserContext(browser_context)));
|
| - BroadcastItemStateChanged(
|
| - browser_context, developer::EVENT_TYPE_LOADED, extension->id());
|
| + BroadcastItemStateChanged(developer::EVENT_TYPE_LOADED, extension->id());
|
| }
|
|
|
| void DeveloperPrivateEventRouter::OnExtensionUnloaded(
|
| @@ -280,8 +223,7 @@ void DeveloperPrivateEventRouter::OnExtensionUnloaded(
|
| const Extension* extension,
|
| UnloadedExtensionInfo::Reason reason) {
|
| DCHECK(profile_->IsSameProfile(Profile::FromBrowserContext(browser_context)));
|
| - BroadcastItemStateChanged(
|
| - browser_context, developer::EVENT_TYPE_UNLOADED, extension->id());
|
| + BroadcastItemStateChanged(developer::EVENT_TYPE_UNLOADED, extension->id());
|
| }
|
|
|
| void DeveloperPrivateEventRouter::OnExtensionWillBeInstalled(
|
| @@ -291,8 +233,7 @@ void DeveloperPrivateEventRouter::OnExtensionWillBeInstalled(
|
| bool from_ephemeral,
|
| const std::string& old_name) {
|
| DCHECK(profile_->IsSameProfile(Profile::FromBrowserContext(browser_context)));
|
| - BroadcastItemStateChanged(
|
| - browser_context, developer::EVENT_TYPE_INSTALLED, extension->id());
|
| + BroadcastItemStateChanged(developer::EVENT_TYPE_INSTALLED, extension->id());
|
| }
|
|
|
| void DeveloperPrivateEventRouter::OnExtensionUninstalled(
|
| @@ -300,8 +241,7 @@ void DeveloperPrivateEventRouter::OnExtensionUninstalled(
|
| const Extension* extension,
|
| extensions::UninstallReason reason) {
|
| DCHECK(profile_->IsSameProfile(Profile::FromBrowserContext(browser_context)));
|
| - BroadcastItemStateChanged(
|
| - browser_context, developer::EVENT_TYPE_UNINSTALLED, extension->id());
|
| + BroadcastItemStateChanged(developer::EVENT_TYPE_UNINSTALLED, extension->id());
|
| }
|
|
|
| void DeveloperPrivateEventRouter::OnErrorAdded(const ExtensionError* error) {
|
| @@ -311,40 +251,81 @@ void DeveloperPrivateEventRouter::OnErrorAdded(const ExtensionError* error) {
|
| if (extension_ids_.find(error->extension_id()) != extension_ids_.end())
|
| return;
|
|
|
| - BroadcastItemStateChanged(
|
| - profile_, developer::EVENT_TYPE_ERROR_ADDED, error->extension_id());
|
| + BroadcastItemStateChanged(developer::EVENT_TYPE_ERROR_ADDED,
|
| + error->extension_id());
|
| }
|
|
|
| void DeveloperPrivateEventRouter::OnExtensionFrameRegistered(
|
| const std::string& extension_id,
|
| content::RenderFrameHost* render_frame_host) {
|
| - BroadcastItemStateChanged(
|
| - profile_, developer::EVENT_TYPE_VIEW_REGISTERED, extension_id);
|
| + BroadcastItemStateChanged(developer::EVENT_TYPE_VIEW_REGISTERED,
|
| + extension_id);
|
| }
|
|
|
| void DeveloperPrivateEventRouter::OnExtensionFrameUnregistered(
|
| const std::string& extension_id,
|
| content::RenderFrameHost* render_frame_host) {
|
| - BroadcastItemStateChanged(
|
| - profile_, developer::EVENT_TYPE_VIEW_UNREGISTERED, extension_id);
|
| + BroadcastItemStateChanged(developer::EVENT_TYPE_VIEW_UNREGISTERED,
|
| + extension_id);
|
| }
|
|
|
| void DeveloperPrivateEventRouter::OnAppWindowAdded(AppWindow* window) {
|
| - BroadcastItemStateChanged(
|
| - profile_, developer::EVENT_TYPE_VIEW_REGISTERED, window->extension_id());
|
| + BroadcastItemStateChanged(developer::EVENT_TYPE_VIEW_REGISTERED,
|
| + window->extension_id());
|
| }
|
|
|
| void DeveloperPrivateEventRouter::OnAppWindowRemoved(AppWindow* window) {
|
| - BroadcastItemStateChanged(profile_,
|
| - developer::EVENT_TYPE_VIEW_UNREGISTERED,
|
| + BroadcastItemStateChanged(developer::EVENT_TYPE_VIEW_UNREGISTERED,
|
| window->extension_id());
|
| }
|
|
|
| void DeveloperPrivateEventRouter::OnExtensionActionVisibilityChanged(
|
| const std::string& extension_id,
|
| bool is_now_visible) {
|
| - BroadcastItemStateChanged(
|
| - profile_, developer::EVENT_TYPE_PREFS_CHANGED, extension_id);
|
| + BroadcastItemStateChanged(developer::EVENT_TYPE_PREFS_CHANGED, extension_id);
|
| +}
|
| +
|
| +void DeveloperPrivateEventRouter::BroadcastItemStateChanged(
|
| + developer::EventType event_type,
|
| + const std::string& extension_id) {
|
| + scoped_ptr<ExtensionInfoGenerator> info_generator(
|
| + new ExtensionInfoGenerator(profile_));
|
| + ExtensionInfoGenerator* info_generator_weak = info_generator.get();
|
| + info_generator_weak->CreateExtensionInfo(
|
| + extension_id,
|
| + base::Bind(&DeveloperPrivateEventRouter::BroadcastItemStateChangedHelper,
|
| + weak_factory_.GetWeakPtr(),
|
| + event_type,
|
| + extension_id,
|
| + base::Passed(info_generator.Pass())));
|
| +}
|
| +
|
| +void DeveloperPrivateEventRouter::BroadcastItemStateChangedHelper(
|
| + developer::EventType event_type,
|
| + const std::string& extension_id,
|
| + scoped_ptr<ExtensionInfoGenerator> info_generator,
|
| + const ExtensionInfoGenerator::ExtensionInfoList& infos) {
|
| + DCHECK_LE(infos.size(), 1u);
|
| +
|
| + developer::EventData event_data;
|
| + event_data.event_type = event_type;
|
| + event_data.item_id = extension_id;
|
| + scoped_ptr<base::DictionaryValue> dict = event_data.ToValue();
|
| +
|
| + if (!infos.empty()) {
|
| + // Hack: Ideally, we would use event_data.extension_info to set the
|
| + // extension info, but since it's an optional field, it's implemented as a
|
| + // scoped ptr, and so ownership between that and the vector of linked ptrs
|
| + // here is, well, messy. Easier to just set it like this.
|
| + dict->SetWithoutPathExpansion("extensionInfo",
|
| + infos[0]->ToValue().release());
|
| + }
|
| +
|
| + scoped_ptr<base::ListValue> args(new base::ListValue());
|
| + args->Append(dict.release());
|
| + scoped_ptr<Event> event(new Event(
|
| + developer::OnItemStateChanged::kEventName, args.Pass()));
|
| + event_router_->BroadcastEvent(event.Pass());
|
| }
|
|
|
| void DeveloperPrivateAPI::SetLastUnpackedDirectory(const base::FilePath& path) {
|
| @@ -353,7 +334,7 @@ void DeveloperPrivateAPI::SetLastUnpackedDirectory(const base::FilePath& path) {
|
|
|
| void DeveloperPrivateAPI::RegisterNotifications() {
|
| EventRouter::Get(profile_)->RegisterObserver(
|
| - this, developer_private::OnItemStateChanged::kEventName);
|
| + this, developer::OnItemStateChanged::kEventName);
|
| }
|
|
|
| DeveloperPrivateAPI::~DeveloperPrivateAPI() {}
|
| @@ -373,7 +354,7 @@ void DeveloperPrivateAPI::OnListenerAdded(
|
| void DeveloperPrivateAPI::OnListenerRemoved(
|
| const EventListenerInfo& details) {
|
| if (!EventRouter::Get(profile_)->HasEventListener(
|
| - developer_private::OnItemStateChanged::kEventName)) {
|
| + developer::OnItemStateChanged::kEventName)) {
|
| developer_private_event_router_.reset(NULL);
|
| } else {
|
| developer_private_event_router_->RemoveExtensionId(details.extension_id);
|
| @@ -411,6 +392,10 @@ ExtensionFunction::ResponseAction DeveloperPrivateAutoUpdateFunction::Run() {
|
| }
|
|
|
| DeveloperPrivateGetExtensionsInfoFunction::
|
| +DeveloperPrivateGetExtensionsInfoFunction() {
|
| +}
|
| +
|
| +DeveloperPrivateGetExtensionsInfoFunction::
|
| ~DeveloperPrivateGetExtensionsInfoFunction() {
|
| }
|
|
|
| @@ -429,12 +414,23 @@ DeveloperPrivateGetExtensionsInfoFunction::Run() {
|
| include_terminated = *params->options->include_terminated;
|
| }
|
|
|
| - std::vector<linked_ptr<developer::ExtensionInfo>> list =
|
| - ExtensionInfoGenerator(browser_context()).
|
| - CreateExtensionsInfo(include_disabled, include_terminated);
|
| + info_generator_.reset(new ExtensionInfoGenerator(browser_context()));
|
| + info_generator_->CreateExtensionsInfo(
|
| + include_disabled,
|
| + include_terminated,
|
| + base::Bind(&DeveloperPrivateGetExtensionsInfoFunction::OnInfosGenerated,
|
| + this /* refcounted */));
|
| +
|
| + return RespondLater();
|
| +}
|
| +
|
| +void DeveloperPrivateGetExtensionsInfoFunction::OnInfosGenerated(
|
| + const ExtensionInfoGenerator::ExtensionInfoList& list) {
|
| + Respond(ArgumentList(developer::GetExtensionsInfo::Results::Create(list)));
|
| +}
|
|
|
| - return RespondNow(ArgumentList(
|
| - developer::GetExtensionsInfo::Results::Create(list)));
|
| +DeveloperPrivateGetExtensionInfoFunction::
|
| +DeveloperPrivateGetExtensionInfoFunction() {
|
| }
|
|
|
| DeveloperPrivateGetExtensionInfoFunction::
|
| @@ -447,13 +443,21 @@ DeveloperPrivateGetExtensionInfoFunction::Run() {
|
| developer::GetExtensionInfo::Params::Create(*args_));
|
| EXTENSION_FUNCTION_VALIDATE(params);
|
|
|
| - scoped_ptr<developer::ExtensionInfo> info =
|
| - ExtensionInfoGenerator(browser_context()).CreateExtensionInfo(params->id);
|
| + info_generator_.reset(new ExtensionInfoGenerator(browser_context()));
|
| + info_generator_->CreateExtensionInfo(
|
| + params->id,
|
| + base::Bind(&DeveloperPrivateGetExtensionInfoFunction::OnInfosGenerated,
|
| + this /* refcounted */));
|
|
|
| - if (!info)
|
| - return RespondNow(Error(kNoSuchExtensionError));
|
| + return RespondLater();
|
| +}
|
|
|
| - return RespondNow(OneArgument(info->ToValue().release()));
|
| +void DeveloperPrivateGetExtensionInfoFunction::OnInfosGenerated(
|
| + const ExtensionInfoGenerator::ExtensionInfoList& list) {
|
| + DCHECK_EQ(1u, list.size());
|
| + const linked_ptr<developer::ExtensionInfo>& info = list[0];
|
| + Respond(info.get() ? OneArgument(info->ToValue()) :
|
| + Error(kNoSuchExtensionError));
|
| }
|
|
|
| DeveloperPrivateGetItemsInfoFunction::DeveloperPrivateGetItemsInfoFunction() {}
|
| @@ -464,63 +468,23 @@ ExtensionFunction::ResponseAction DeveloperPrivateGetItemsInfoFunction::Run() {
|
| developer::GetItemsInfo::Params::Create(*args_));
|
| EXTENSION_FUNCTION_VALIDATE(params);
|
|
|
| - ExtensionSet items;
|
| - ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context());
|
| - items.InsertAll(registry->enabled_extensions());
|
| -
|
| - if (params->include_disabled)
|
| - items.InsertAll(registry->disabled_extensions());
|
| - if (params->include_terminated)
|
| - items.InsertAll(registry->terminated_extensions());
|
| -
|
| - std::map<std::string, ExtensionResource> resource_map;
|
| - for (const scoped_refptr<const Extension>& item : items) {
|
| - // Don't show component extensions and invisible apps.
|
| - if (ui_util::ShouldDisplayInExtensionSettings(item.get(),
|
| - browser_context())) {
|
| - resource_map[item->id()] =
|
| - IconsInfo::GetIconResource(item.get(),
|
| - extension_misc::EXTENSION_ICON_MEDIUM,
|
| - ExtensionIconSet::MATCH_BIGGER);
|
| - }
|
| - }
|
| -
|
| - std::vector<linked_ptr<developer::ExtensionInfo>> list =
|
| - ExtensionInfoGenerator(browser_context()).
|
| - CreateExtensionsInfo(params->include_disabled,
|
| - params->include_terminated);
|
| -
|
| - for (const linked_ptr<developer::ExtensionInfo>& info : list)
|
| - item_list_.push_back(developer_private_mangle::MangleExtensionInfo(*info));
|
| -
|
| - content::BrowserThread::PostTask(
|
| - content::BrowserThread::FILE,
|
| - FROM_HERE,
|
| - base::Bind(&DeveloperPrivateGetItemsInfoFunction::GetIconsOnFileThread,
|
| - this,
|
| - resource_map));
|
| + info_generator_.reset(new ExtensionInfoGenerator(browser_context()));
|
| + info_generator_->CreateExtensionsInfo(
|
| + params->include_disabled,
|
| + params->include_terminated,
|
| + base::Bind(&DeveloperPrivateGetItemsInfoFunction::OnInfosGenerated,
|
| + this /* refcounted */));
|
|
|
| return RespondLater();
|
| }
|
|
|
| -void DeveloperPrivateGetItemsInfoFunction::GetIconsOnFileThread(
|
| - const std::map<std::string, ExtensionResource> resource_map) {
|
| - for (const linked_ptr<developer::ItemInfo>& item : item_list_) {
|
| - auto resource = resource_map.find(item->id);
|
| - if (resource != resource_map.end()) {
|
| - item->icon_url = ToDataURL(resource->second.GetFilePath(),
|
| - item->type).spec();
|
| - }
|
| - }
|
| -
|
| - content::BrowserThread::PostTask(
|
| - content::BrowserThread::UI,
|
| - FROM_HERE,
|
| - base::Bind(&DeveloperPrivateGetItemsInfoFunction::Finish, this));
|
| -}
|
| +void DeveloperPrivateGetItemsInfoFunction::OnInfosGenerated(
|
| + const ExtensionInfoGenerator::ExtensionInfoList& list) {
|
| + std::vector<linked_ptr<developer::ItemInfo>> item_list;
|
| + for (const linked_ptr<developer::ExtensionInfo>& info : list)
|
| + item_list.push_back(developer_private_mangle::MangleExtensionInfo(*info));
|
|
|
| -void DeveloperPrivateGetItemsInfoFunction::Finish() {
|
| - Respond(ArgumentList(developer::GetItemsInfo::Results::Create(item_list_)));
|
| + Respond(ArgumentList(developer::GetItemsInfo::Results::Create(item_list)));
|
| }
|
|
|
| DeveloperPrivateGetProfileConfigurationFunction::
|
| @@ -685,8 +649,8 @@ DeveloperPrivateLoadUnpackedFunction::DeveloperPrivateLoadUnpackedFunction()
|
| }
|
|
|
| ExtensionFunction::ResponseAction DeveloperPrivateLoadUnpackedFunction::Run() {
|
| - scoped_ptr<developer_private::LoadUnpacked::Params> params(
|
| - developer_private::LoadUnpacked::Params::Create(*args_));
|
| + scoped_ptr<developer::LoadUnpacked::Params> params(
|
| + developer::LoadUnpacked::Params::Create(*args_));
|
| EXTENSION_FUNCTION_VALIDATE(params);
|
|
|
| if (!ShowPicker(
|
| @@ -766,7 +730,7 @@ void DeveloperPrivatePackDirectoryFunction::OnPackSuccess(
|
| response.message = base::UTF16ToUTF8(
|
| PackExtensionJob::StandardSuccessMessage(crx_file, pem_file));
|
| response.status = developer::PACK_STATUS_SUCCESS;
|
| - Respond(OneArgument(response.ToValue().release()));
|
| + Respond(OneArgument(response.ToValue()));
|
| Release(); // Balanced in Run().
|
| }
|
|
|
| @@ -783,7 +747,7 @@ void DeveloperPrivatePackDirectoryFunction::OnPackFailure(
|
| } else {
|
| response.status = developer::PACK_STATUS_ERROR;
|
| }
|
| - Respond(OneArgument(response.ToValue().release()));
|
| + Respond(OneArgument(response.ToValue()));
|
| Release(); // Balanced in Run().
|
| }
|
|
|
| @@ -811,14 +775,14 @@ ExtensionFunction::ResponseAction DeveloperPrivatePackDirectoryFunction::Run() {
|
| IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID);
|
|
|
| response.status = developer::PACK_STATUS_ERROR;
|
| - return RespondNow(OneArgument(response.ToValue().release()));
|
| + return RespondNow(OneArgument(response.ToValue()));
|
| }
|
|
|
| if (!key_path_str_.empty() && key_file.empty()) {
|
| response.message = l10n_util::GetStringUTF8(
|
| IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID);
|
| response.status = developer::PACK_STATUS_ERROR;
|
| - return RespondNow(OneArgument(response.ToValue().release()));
|
| + return RespondNow(OneArgument(response.ToValue()));
|
| }
|
|
|
| AddRef(); // Balanced in OnPackSuccess / OnPackFailure.
|
| @@ -1205,7 +1169,7 @@ void DeveloperPrivateRequestFileSourceFunction::Finish(
|
| response.highlight = highlighter->GetFeature();
|
| response.after_highlight = highlighter->GetAfterFeature();
|
|
|
| - Respond(OneArgument(response.ToValue().release()));
|
| + Respond(OneArgument(response.ToValue()));
|
| }
|
|
|
| DeveloperPrivateOpenDevToolsFunction::DeveloperPrivateOpenDevToolsFunction() {}
|
|
|