| 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 5be12ef9e4352a0555c3c074c5002b4506da6421..02e77c1be47f648227fa40f884454640e30797de 100644
|
| --- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
|
| +++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
|
| @@ -9,32 +9,30 @@
|
| #include "base/base64.h"
|
| #include "base/bind.h"
|
| #include "base/command_line.h"
|
| -#include "base/files/file_enumerator.h"
|
| #include "base/files/file_util.h"
|
| -#include "base/i18n/file_util_icu.h"
|
| #include "base/lazy_instance.h"
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/strings/stringprintf.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "base/values.h"
|
| #include "chrome/browser/devtools/devtools_window.h"
|
| +#include "chrome/browser/extensions/api/developer_private/developer_private_mangle.h"
|
| #include "chrome/browser/extensions/api/developer_private/entry_picker.h"
|
| +#include "chrome/browser/extensions/api/developer_private/inspectable_views_finder.h"
|
| #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
|
| #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
|
| #include "chrome/browser/extensions/chrome_requirements_checker.h"
|
| #include "chrome/browser/extensions/devtools_util.h"
|
| -#include "chrome/browser/extensions/extension_disabled_ui.h"
|
| -#include "chrome/browser/extensions/extension_error_reporter.h"
|
| #include "chrome/browser/extensions/extension_service.h"
|
| #include "chrome/browser/extensions/extension_ui_util.h"
|
| #include "chrome/browser/extensions/extension_util.h"
|
| +#include "chrome/browser/extensions/path_util.h"
|
| +#include "chrome/browser/extensions/shared_module_service.h"
|
| #include "chrome/browser/extensions/unpacked_installer.h"
|
| #include "chrome/browser/extensions/updater/extension_updater.h"
|
| #include "chrome/browser/platform_util.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
|
| #include "chrome/browser/ui/browser_finder.h"
|
| -#include "chrome/browser/ui/chrome_select_file_policy.h"
|
| #include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
|
| #include "chrome/common/extensions/api/developer_private.h"
|
| @@ -58,10 +56,11 @@
|
| #include "extensions/browser/file_highlighter.h"
|
| #include "extensions/browser/management_policy.h"
|
| #include "extensions/browser/notification_types.h"
|
| -#include "extensions/browser/view_type_utils.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/background_info.h"
|
| @@ -74,7 +73,6 @@
|
| #include "extensions/common/switches.h"
|
| #include "extensions/grit/extensions_browser_resources.h"
|
| #include "net/base/net_util.h"
|
| -#include "storage/browser/blob/shareable_file_reference.h"
|
| #include "storage/browser/fileapi/external_mount_points.h"
|
| #include "storage/browser/fileapi/file_system_context.h"
|
| #include "storage/browser/fileapi/file_system_operation.h"
|
| @@ -84,8 +82,6 @@
|
| #include "ui/base/resource/resource_bundle.h"
|
| #include "ui/base/webui/web_ui_util.h"
|
|
|
| -using content::RenderViewHost;
|
| -
|
| namespace extensions {
|
|
|
| namespace developer_private = api::developer_private;
|
| @@ -157,7 +153,7 @@ GURL ToDataURL(const base::FilePath& path, developer_private::ItemType type) {
|
| return GetImageURLFromData(contents);
|
| }
|
|
|
| -std::string GetExtensionID(const RenderViewHost* render_view_host) {
|
| +std::string GetExtensionID(const content::RenderViewHost* render_view_host) {
|
| if (!render_view_host->GetSiteInstance())
|
| return std::string();
|
|
|
| @@ -184,6 +180,348 @@ std::string ReadFileToString(const base::FilePath& path) {
|
| return data;
|
| }
|
|
|
| +// Populates the common fields of an extension error.
|
| +template <typename ErrorType>
|
| +void PopulateErrorBase(const ExtensionError& error,
|
| + ErrorType* out) {
|
| + CHECK(out);
|
| + out->type = error.type() == ExtensionError::MANIFEST_ERROR ?
|
| + developer::ERROR_TYPE_MANIFEST : developer::ERROR_TYPE_RUNTIME;
|
| + out->extension_id = error.extension_id();
|
| + out->from_incognito = error.from_incognito();
|
| + out->source = base::UTF16ToUTF8(error.source());
|
| + out->message = base::UTF16ToUTF8(error.message());
|
| +}
|
| +
|
| +// Given a ManifestError object, converts it into its developer_private
|
| +// counterpart.
|
| +linked_ptr<developer::ManifestError> ConstructManifestError(
|
| + const ManifestError& error) {
|
| + linked_ptr<developer::ManifestError> result(new developer::ManifestError());
|
| + PopulateErrorBase(error, result.get());
|
| + result->manifest_key = base::UTF16ToUTF8(error.manifest_key());
|
| + if (!error.manifest_specific().empty()) {
|
| + result->manifest_specific.reset(
|
| + new std::string(base::UTF16ToUTF8(error.manifest_specific())));
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +// Given a RuntimeError object, converts it into its developer_private
|
| +// counterpart.
|
| +linked_ptr<developer::RuntimeError> ConstructRuntimeError(
|
| + const RuntimeError& error) {
|
| + linked_ptr<developer::RuntimeError> result(new developer::RuntimeError());
|
| + PopulateErrorBase(error, result.get());
|
| + switch (error.level()) {
|
| + case logging::LOG_INFO:
|
| + result->severity = developer::ERROR_LEVEL_LOG;
|
| + break;
|
| + case logging::LOG_WARNING:
|
| + result->severity = developer::ERROR_LEVEL_WARN;
|
| + break;
|
| + case logging::LOG_ERROR:
|
| + result->severity = developer::ERROR_LEVEL_ERROR;
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| + result->occurrences = error.occurrences();
|
| + result->render_view_id = error.render_view_id();
|
| + result->render_process_id = error.render_process_id();
|
| + result->can_inspect =
|
| + content::RenderViewHost::FromID(error.render_process_id(),
|
| + error.render_view_id()) != nullptr;
|
| + for (const StackFrame& f : error.stack_trace()) {
|
| + linked_ptr<developer::StackFrame> frame(new developer::StackFrame());
|
| + frame->line_number = f.line_number;
|
| + frame->column_number = f.column_number;
|
| + frame->url = base::UTF16ToUTF8(f.source);
|
| + frame->function_name = base::UTF16ToUTF8(f.function);
|
| + result->stack_trace.push_back(frame);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +// Given a Manifest::Type, converts it into its developer_private
|
| +// counterpart.
|
| +developer::ExtensionType GetExtensionType(Manifest::Type manifest_type) {
|
| + developer::ExtensionType type = developer::EXTENSION_TYPE_EXTENSION;
|
| + switch (manifest_type) {
|
| + case Manifest::TYPE_EXTENSION:
|
| + type = developer::EXTENSION_TYPE_EXTENSION;
|
| + break;
|
| + case Manifest::TYPE_THEME:
|
| + type = developer::EXTENSION_TYPE_THEME;
|
| + break;
|
| + case Manifest::TYPE_HOSTED_APP:
|
| + type = developer::EXTENSION_TYPE_HOSTED_APP;
|
| + break;
|
| + case Manifest::TYPE_LEGACY_PACKAGED_APP:
|
| + type = developer::EXTENSION_TYPE_LEGACY_PACKAGED_APP;
|
| + break;
|
| + case Manifest::TYPE_PLATFORM_APP:
|
| + type = developer::EXTENSION_TYPE_PLATFORM_APP;
|
| + break;
|
| + case Manifest::TYPE_SHARED_MODULE:
|
| + type = developer::EXTENSION_TYPE_SHARED_MODULE;
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| + return type;
|
| +}
|
| +
|
| +// Constructs information about a given |extension|.
|
| +scoped_ptr<developer::ExtensionInfo> CreateExtensionInfo(
|
| + const Extension& extension,
|
| + developer::ExtensionState state,
|
| + content::BrowserContext* browser_context) {
|
| + scoped_ptr<developer::ExtensionInfo> info(new developer::ExtensionInfo());
|
| +
|
| + ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context);
|
| + // Don't consider the button hidden with the redesign, because "hidden"
|
| + // buttons are now just hidden in the wrench menu.
|
| + info->action_button_hidden =
|
| + !ExtensionActionAPI::GetBrowserActionVisibility(prefs, extension.id()) &&
|
| + !FeatureSwitch::extension_action_redesign()->IsEnabled();
|
| +
|
| + // Blacklist text.
|
| + int blacklist_text = -1;
|
| + switch (prefs->GetExtensionBlacklistState(extension.id())) {
|
| + case BLACKLISTED_SECURITY_VULNERABILITY:
|
| + blacklist_text = IDS_OPTIONS_BLACKLISTED_SECURITY_VULNERABILITY;
|
| + break;
|
| + case BLACKLISTED_CWS_POLICY_VIOLATION:
|
| + blacklist_text = IDS_OPTIONS_BLACKLISTED_CWS_POLICY_VIOLATION;
|
| + break;
|
| + case BLACKLISTED_POTENTIALLY_UNWANTED:
|
| + blacklist_text = IDS_OPTIONS_BLACKLISTED_POTENTIALLY_UNWANTED;
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + if (blacklist_text != -1) {
|
| + info->blacklist_text.reset(
|
| + new std::string(l10n_util::GetStringUTF8(blacklist_text)));
|
| + }
|
| +
|
| + // Dependent extensions.
|
| + if (extension.is_shared_module()) {
|
| + scoped_ptr<ExtensionSet> dependent_extensions =
|
| + ExtensionSystem::Get(browser_context)->extension_service()->
|
| + shared_module_service()->GetDependentExtensions(&extension);
|
| + for (const scoped_refptr<const Extension>& dependent :
|
| + *dependent_extensions)
|
| + info->dependent_extensions.push_back(dependent->id());
|
| + }
|
| +
|
| + info->description = extension.description();
|
| +
|
| + // Disable reasons.
|
| + int disable_reasons = prefs->GetDisableReasons(extension.id());
|
| + info->disable_reasons.suspicious_install =
|
| + (disable_reasons & Extension::DISABLE_NOT_VERIFIED) != 0;
|
| + info->disable_reasons.corrupt_install =
|
| + (disable_reasons & Extension::DISABLE_CORRUPTED) != 0;
|
| + info->disable_reasons.update_required =
|
| + (disable_reasons & Extension::DISABLE_UPDATE_REQUIRED_BY_POLICY) != 0;
|
| +
|
| + // Error collection.
|
| + Profile* profile = Profile::FromBrowserContext(browser_context);
|
| + ErrorConsole* error_console = ErrorConsole::Get(profile);
|
| + bool error_console_enabled =
|
| + error_console->IsEnabledForChromeExtensionsPage();
|
| + info->error_collection.is_enabled = error_console_enabled;
|
| + info->error_collection.is_active =
|
| + error_console_enabled &&
|
| + error_console->IsReportingEnabledForExtension(extension.id());
|
| +
|
| + // File access.
|
| + info->file_access.is_enabled = extension.wants_file_access();
|
| + info->file_access.is_active =
|
| + util::AllowFileAccess(extension.id(), browser_context);
|
| +
|
| + // Home page.
|
| + info->home_page.url = ManifestURL::GetHomepageURL(&extension).spec();
|
| + info->home_page.specified = ManifestURL::SpecifiedHomepageURL(&extension);
|
| +
|
| + bool is_enabled = state == developer::EXTENSION_STATE_ENABLED;
|
| +
|
| + // TODO(devlin): This won't work with apps (CORS). We should convert to data
|
| + // urls.
|
| + info->icon_url =
|
| + ExtensionIconSource::GetIconURL(&extension,
|
| + extension_misc::EXTENSION_ICON_MEDIUM,
|
| + ExtensionIconSet::MATCH_BIGGER,
|
| + !is_enabled,
|
| + nullptr).spec();
|
| +
|
| + info->id = extension.id();
|
| +
|
| + // Incognito access.
|
| + info->incognito_access.is_enabled = extension.can_be_incognito_enabled();
|
| + info->incognito_access.is_active =
|
| + util::IsIncognitoEnabled(extension.id(), browser_context);
|
| +
|
| + info->installed_by_custodian =
|
| + util::IsExtensionSupervised(&extension, profile);
|
| +
|
| + // Install warnings (only if unpacked and no error console).
|
| + if (!error_console_enabled &&
|
| + Manifest::IsUnpackedLocation(extension.location())) {
|
| + const std::vector<InstallWarning>& install_warnings =
|
| + extension.install_warnings();
|
| + for (const InstallWarning& warning : install_warnings)
|
| + info->install_warnings.push_back(warning.message);
|
| + }
|
| +
|
| + // Launch url.
|
| + if (extension.is_app()) {
|
| + info->launch_url.reset(
|
| + new std::string(AppLaunchInfo::GetFullLaunchURL(&extension).spec()));
|
| + }
|
| +
|
| + // Location.
|
| + if (extension.location() == Manifest::INTERNAL &&
|
| + ManifestURL::UpdatesFromGallery(&extension)) {
|
| + info->location = developer::LOCATION_FROM_STORE;
|
| + } else if (Manifest::IsUnpackedLocation(extension.location())) {
|
| + info->location = developer::LOCATION_UNPACKED;
|
| + } else {
|
| + info->location = developer::LOCATION_UNKNOWN;
|
| + }
|
| +
|
| + // Location text.
|
| + int location_text = -1;
|
| + if (info->location == developer::LOCATION_UNKNOWN)
|
| + location_text = IDS_OPTIONS_INSTALL_LOCATION_UNKNOWN;
|
| + else if (extension.location() == Manifest::EXTERNAL_REGISTRY)
|
| + location_text = IDS_OPTIONS_INSTALL_LOCATION_3RD_PARTY;
|
| + else if (extension.is_shared_module())
|
| + location_text = IDS_OPTIONS_INSTALL_LOCATION_SHARED_MODULE;
|
| + if (location_text != -1) {
|
| + info->location_text.reset(
|
| + new std::string(l10n_util::GetStringUTF8(location_text)));
|
| + }
|
| +
|
| + // Runtime/Manifest errors.
|
| + if (error_console_enabled) {
|
| + const ErrorList& errors =
|
| + error_console->GetErrorsForExtension(extension.id());
|
| + for (const ExtensionError* error : errors) {
|
| + switch (error->type()) {
|
| + case ExtensionError::MANIFEST_ERROR:
|
| + info->manifest_errors.push_back(ConstructManifestError(
|
| + static_cast<const ManifestError&>(*error)));
|
| + break;
|
| + case ExtensionError::RUNTIME_ERROR:
|
| + info->runtime_errors.push_back(ConstructRuntimeError(
|
| + static_cast<const RuntimeError&>(*error)));
|
| + break;
|
| + case ExtensionError::NUM_ERROR_TYPES:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| + }
|
| + }
|
| +
|
| + ManagementPolicy* management_policy =
|
| + ExtensionSystem::Get(browser_context)->management_policy();
|
| + info->must_remain_installed =
|
| + management_policy->MustRemainInstalled(&extension, nullptr);
|
| +
|
| + info->name = extension.name();
|
| + info->offline_enabled = OfflineEnabledInfo::IsOfflineEnabled(&extension);
|
| +
|
| + // Options page.
|
| + if (OptionsPageInfo::HasOptionsPage(&extension)) {
|
| + info->options_page.reset(new developer::OptionsPage());
|
| + info->options_page->open_in_tab =
|
| + OptionsPageInfo::ShouldOpenInTab(&extension);
|
| + info->options_page->url =
|
| + OptionsPageInfo::GetOptionsPage(&extension).spec();
|
| + }
|
| +
|
| + // Path.
|
| + if (Manifest::IsUnpackedLocation(extension.location())) {
|
| + info->path.reset(new std::string(extension.path().AsUTF8Unsafe()));
|
| + info->prettified_path.reset(new std::string(
|
| + extensions::path_util::PrettifyPath(extension.path()).AsUTF8Unsafe()));
|
| + }
|
| +
|
| + if (Manifest::IsPolicyLocation(extension.location())) {
|
| + info->policy_text.reset(new std::string(
|
| + l10n_util::GetStringUTF8(IDS_OPTIONS_INSTALL_LOCATION_ENTERPRISE)));
|
| + }
|
| +
|
| + // Runs on all urls.
|
| + info->run_on_all_urls.is_enabled =
|
| + (FeatureSwitch::scripts_require_action()->IsEnabled() &&
|
| + PermissionsData::ScriptsMayRequireActionForExtension(
|
| + &extension,
|
| + extension.permissions_data()->active_permissions().get())) ||
|
| + extension.permissions_data()->HasWithheldImpliedAllHosts() ||
|
| + util::HasSetAllowedScriptingOnAllUrls(extension.id(), browser_context);
|
| + info->run_on_all_urls.is_active =
|
| + util::AllowedScriptingOnAllUrls(extension.id(), browser_context);
|
| +
|
| + // Runtime warnings.
|
| + WarningService* warning_service = WarningService::Get(profile);
|
| + std::vector<std::string> warnings =
|
| + warning_service->GetWarningMessagesForExtension(extension.id());
|
| + for (const std::string& warning : warnings)
|
| + info->runtime_warnings.push_back(warning);
|
| +
|
| + info->state = state;
|
| +
|
| + info->type = GetExtensionType(extension.manifest()->type());
|
| +
|
| + info->update_url = ManifestURL::GetUpdateURL(&extension).spec();
|
| +
|
| + info->user_may_modify =
|
| + management_policy->UserMayModifySettings(&extension, nullptr);
|
| +
|
| + info->version = extension.GetVersionForDisplay();
|
| +
|
| + if (state != developer::EXTENSION_STATE_TERMINATED) {
|
| + info->views = InspectableViewsFinder(profile, nullptr).
|
| + GetViewsForExtension(extension, is_enabled);
|
| + }
|
| + return info.Pass();
|
| +}
|
| +
|
| +std::vector<linked_ptr<developer::ExtensionInfo>> GetExtensionsInfo(
|
| + content::BrowserContext* context,
|
| + bool include_disabled,
|
| + bool include_terminated) {
|
| + std::vector<linked_ptr<developer::ExtensionInfo>> list;
|
| + auto add_to_list = [&list, context](const ExtensionSet& extensions,
|
| + developer::ExtensionState state) {
|
| + for (const scoped_refptr<const Extension>& extension : extensions) {
|
| + if (ui_util::ShouldDisplayInExtensionSettings(extension.get(), context)) {
|
| + scoped_ptr<developer::ExtensionInfo> info =
|
| + CreateExtensionInfo(*extension, state, context);
|
| + list.push_back(make_linked_ptr(info.release()));
|
| + }
|
| + }
|
| + };
|
| +
|
| + ExtensionRegistry* registry = ExtensionRegistry::Get(context);
|
| + add_to_list(registry->enabled_extensions(),
|
| + developer::EXTENSION_STATE_ENABLED);
|
| + if (include_disabled) {
|
| + add_to_list(registry->disabled_extensions(),
|
| + developer::EXTENSION_STATE_DISABLED);
|
| + }
|
| + if (include_terminated) {
|
| + add_to_list(registry->terminated_extensions(),
|
| + developer::EXTENSION_STATE_TERMINATED);
|
| + }
|
| +
|
| + return list;
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace AllowFileAccess = api::developer_private::AllowFileAccess;
|
| @@ -256,13 +594,13 @@ void DeveloperPrivateEventRouter::Observe(
|
| case extensions::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED: {
|
| event_data.event_type = developer::EVENT_TYPE_VIEW_UNREGISTERED;
|
| event_data.item_id = GetExtensionID(
|
| - content::Details<const RenderViewHost>(details).ptr());
|
| + content::Details<const content::RenderViewHost>(details).ptr());
|
| break;
|
| }
|
| case extensions::NOTIFICATION_EXTENSION_VIEW_REGISTERED: {
|
| event_data.event_type = developer::EVENT_TYPE_VIEW_REGISTERED;
|
| event_data.item_id = GetExtensionID(
|
| - content::Details<const RenderViewHost>(details).ptr());
|
| + content::Details<const content::RenderViewHost>(details).ptr());
|
| break;
|
| }
|
| default:
|
| @@ -375,333 +713,131 @@ bool DeveloperPrivateAutoUpdateFunction::RunSync() {
|
|
|
| DeveloperPrivateAutoUpdateFunction::~DeveloperPrivateAutoUpdateFunction() {}
|
|
|
| -scoped_ptr<developer::ItemInfo>
|
| -DeveloperPrivateGetItemsInfoFunction::CreateItemInfo(const Extension& item,
|
| - bool item_is_enabled) {
|
| - scoped_ptr<developer::ItemInfo> info(new developer::ItemInfo());
|
| -
|
| - ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
|
| - ExtensionService* service = system->extension_service();
|
| - ExtensionRegistry* registry = ExtensionRegistry::Get(GetProfile());
|
| -
|
| - info->id = item.id();
|
| - info->name = item.name();
|
| - info->enabled = service->IsExtensionEnabled(info->id);
|
| - info->offline_enabled = OfflineEnabledInfo::IsOfflineEnabled(&item);
|
| - info->version = item.VersionString();
|
| - info->description = item.description();
|
| -
|
| - if (item.is_app()) {
|
| - if (item.is_legacy_packaged_app())
|
| - info->type = developer::ITEM_TYPE_LEGACY_PACKAGED_APP;
|
| - else if (item.is_hosted_app())
|
| - info->type = developer::ITEM_TYPE_HOSTED_APP;
|
| - else if (item.is_platform_app())
|
| - info->type = developer::ITEM_TYPE_PACKAGED_APP;
|
| - else
|
| - NOTREACHED();
|
| - } else if (item.is_theme()) {
|
| - info->type = developer::ITEM_TYPE_THEME;
|
| - } else if (item.is_extension()) {
|
| - info->type = developer::ITEM_TYPE_EXTENSION;
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| -
|
| - if (Manifest::IsUnpackedLocation(item.location())) {
|
| - info->path.reset(
|
| - new std::string(base::UTF16ToUTF8(item.path().LossyDisplayName())));
|
| - // If the ErrorConsole is enabled and the extension is unpacked, use the
|
| - // more detailed errors from the ErrorConsole. Otherwise, use the install
|
| - // warnings (using both is redundant).
|
| - ErrorConsole* error_console = ErrorConsole::Get(GetProfile());
|
| - if (error_console->IsEnabledForAppsDeveloperTools() &&
|
| - item.location() == Manifest::UNPACKED) {
|
| - const ErrorList& errors = error_console->GetErrorsForExtension(item.id());
|
| - if (!errors.empty()) {
|
| - for (ErrorList::const_iterator iter = errors.begin();
|
| - iter != errors.end();
|
| - ++iter) {
|
| - switch ((*iter)->type()) {
|
| - case ExtensionError::MANIFEST_ERROR:
|
| - info->manifest_errors.push_back(
|
| - make_linked_ptr((*iter)->ToValue().release()));
|
| - break;
|
| - case ExtensionError::RUNTIME_ERROR: {
|
| - const RuntimeError* error =
|
| - static_cast<const RuntimeError*>(*iter);
|
| - scoped_ptr<base::DictionaryValue> value = error->ToValue();
|
| - bool can_inspect = content::RenderViewHost::FromID(
|
| - error->render_process_id(),
|
| - error->render_view_id()) != NULL;
|
| - value->SetBoolean("canInspect", can_inspect);
|
| - info->runtime_errors.push_back(make_linked_ptr(value.release()));
|
| - break;
|
| - }
|
| - case ExtensionError::NUM_ERROR_TYPES:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - } else {
|
| - for (std::vector<InstallWarning>::const_iterator it =
|
| - item.install_warnings().begin();
|
| - it != item.install_warnings().end();
|
| - ++it) {
|
| - scoped_ptr<developer::InstallWarning> warning(
|
| - new developer::InstallWarning);
|
| - warning->message = it->message;
|
| - info->install_warnings.push_back(make_linked_ptr(warning.release()));
|
| - }
|
| - }
|
| - }
|
| -
|
| - info->incognito_enabled = util::IsIncognitoEnabled(item.id(), GetProfile());
|
| - info->wants_file_access = item.wants_file_access();
|
| - info->allow_file_access = util::AllowFileAccess(item.id(), GetProfile());
|
| - info->allow_reload = Manifest::IsUnpackedLocation(item.location());
|
| - info->is_unpacked = Manifest::IsUnpackedLocation(item.location());
|
| - info->terminated = registry->terminated_extensions().Contains(item.id());
|
| - info->allow_incognito = item.can_be_incognito_enabled();
|
| -
|
| - info->homepage_url.reset(new std::string(
|
| - ManifestURL::GetHomepageURL(&item).spec()));
|
| - if (!OptionsPageInfo::GetOptionsPage(&item).is_empty()) {
|
| - info->options_url.reset(
|
| - new std::string(OptionsPageInfo::GetOptionsPage(&item).spec()));
|
| - }
|
| -
|
| - if (!ManifestURL::GetUpdateURL(&item).is_empty()) {
|
| - info->update_url.reset(
|
| - new std::string(ManifestURL::GetUpdateURL(&item).spec()));
|
| - }
|
| -
|
| - if (item.is_app()) {
|
| - info->app_launch_url.reset(
|
| - new std::string(AppLaunchInfo::GetFullLaunchURL(&item).spec()));
|
| - }
|
| -
|
| - info->may_disable = system->management_policy()->
|
| - UserMayModifySettings(&item, NULL);
|
| - info->is_app = item.is_app();
|
| - info->views = GetInspectablePagesForExtension(&item, item_is_enabled);
|
| -
|
| - return info.Pass();
|
| +DeveloperPrivateGetExtensionsInfoFunction::
|
| +~DeveloperPrivateGetExtensionsInfoFunction() {
|
| }
|
|
|
| -void DeveloperPrivateGetItemsInfoFunction::GetIconsOnFileThread(
|
| - ItemInfoList item_list,
|
| - const std::map<std::string, ExtensionResource> idToIcon) {
|
| - for (ItemInfoList::iterator iter = item_list.begin();
|
| - iter != item_list.end(); ++iter) {
|
| - developer_private::ItemInfo* info = iter->get();
|
| - std::map<std::string, ExtensionResource>::const_iterator resource_ptr
|
| - = idToIcon.find(info->id);
|
| - if (resource_ptr != idToIcon.end()) {
|
| - info->icon_url =
|
| - ToDataURL(resource_ptr->second.GetFilePath(), info->type).spec();
|
| - }
|
| +ExtensionFunction::ResponseAction
|
| +DeveloperPrivateGetExtensionsInfoFunction::Run() {
|
| + scoped_ptr<developer::GetExtensionsInfo::Params> params(
|
| + developer::GetExtensionsInfo::Params::Create(*args_));
|
| + EXTENSION_FUNCTION_VALIDATE(params);
|
| +
|
| + bool include_disabled = true;
|
| + bool include_terminated = true;
|
| + if (params->options) {
|
| + if (params->options->include_disabled)
|
| + include_disabled = *params->options->include_disabled;
|
| + if (params->options->include_terminated)
|
| + include_terminated = *params->options->include_terminated;
|
| }
|
|
|
| - results_ = developer::GetItemsInfo::Results::Create(item_list);
|
| - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
| - base::Bind(&DeveloperPrivateGetItemsInfoFunction::SendResponse,
|
| - this,
|
| - true));
|
| -}
|
| -
|
| -void DeveloperPrivateGetItemsInfoFunction::
|
| - GetInspectablePagesForExtensionProcess(
|
| - const Extension* extension,
|
| - const std::set<content::RenderViewHost*>& views,
|
| - ItemInspectViewList* result) {
|
| - bool has_generated_background_page =
|
| - BackgroundInfo::HasGeneratedBackgroundPage(extension);
|
| - for (std::set<content::RenderViewHost*>::const_iterator iter = views.begin();
|
| - iter != views.end(); ++iter) {
|
| - content::RenderViewHost* host = *iter;
|
| - content::WebContents* web_contents =
|
| - content::WebContents::FromRenderViewHost(host);
|
| - ViewType host_type = GetViewType(web_contents);
|
| - if (VIEW_TYPE_EXTENSION_POPUP == host_type ||
|
| - VIEW_TYPE_EXTENSION_DIALOG == host_type)
|
| - continue;
|
| + std::vector<linked_ptr<developer::ExtensionInfo>> list =
|
| + GetExtensionsInfo(browser_context(),
|
| + include_disabled,
|
| + include_terminated);
|
|
|
| - content::RenderProcessHost* process = host->GetProcess();
|
| - bool is_background_page =
|
| - (web_contents->GetURL() == BackgroundInfo::GetBackgroundURL(extension));
|
| - result->push_back(constructInspectView(
|
| - web_contents->GetURL(),
|
| - process->GetID(),
|
| - host->GetRoutingID(),
|
| - process->GetBrowserContext()->IsOffTheRecord(),
|
| - is_background_page && has_generated_background_page));
|
| - }
|
| + return RespondNow(ArgumentList(
|
| + developer::GetExtensionsInfo::Results::Create(list)));
|
| }
|
|
|
| -void DeveloperPrivateGetItemsInfoFunction::GetAppWindowPagesForExtensionProfile(
|
| - const Extension* extension,
|
| - ItemInspectViewList* result) {
|
| - AppWindowRegistry* registry = AppWindowRegistry::Get(GetProfile());
|
| - if (!registry) return;
|
| -
|
| - const AppWindowRegistry::AppWindowList windows =
|
| - registry->GetAppWindowsForApp(extension->id());
|
| -
|
| - bool has_generated_background_page =
|
| - BackgroundInfo::HasGeneratedBackgroundPage(extension);
|
| - for (AppWindowRegistry::const_iterator it = windows.begin();
|
| - it != windows.end();
|
| - ++it) {
|
| - content::WebContents* web_contents = (*it)->web_contents();
|
| - RenderViewHost* host = web_contents->GetRenderViewHost();
|
| - content::RenderProcessHost* process = host->GetProcess();
|
| - bool is_background_page =
|
| - (web_contents->GetURL() == BackgroundInfo::GetBackgroundURL(extension));
|
| - result->push_back(constructInspectView(
|
| - web_contents->GetURL(),
|
| - process->GetID(),
|
| - host->GetRoutingID(),
|
| - process->GetBrowserContext()->IsOffTheRecord(),
|
| - is_background_page && has_generated_background_page));
|
| - }
|
| +DeveloperPrivateGetExtensionInfoFunction::
|
| +~DeveloperPrivateGetExtensionInfoFunction() {
|
| }
|
|
|
| -linked_ptr<developer::ItemInspectView> DeveloperPrivateGetItemsInfoFunction::
|
| - constructInspectView(
|
| - const GURL& url,
|
| - int render_process_id,
|
| - int render_view_id,
|
| - bool incognito,
|
| - bool generated_background_page) {
|
| - linked_ptr<developer::ItemInspectView> view(new developer::ItemInspectView());
|
| +ExtensionFunction::ResponseAction
|
| +DeveloperPrivateGetExtensionInfoFunction::Run() {
|
| + scoped_ptr<developer::GetExtensionInfo::Params> params(
|
| + developer::GetExtensionInfo::Params::Create(*args_));
|
| + EXTENSION_FUNCTION_VALIDATE(params);
|
|
|
| - if (url.scheme() == kExtensionScheme) {
|
| - // No leading slash.
|
| - view->path = url.path().substr(1);
|
| + ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context());
|
| + developer::ExtensionState state = developer::EXTENSION_STATE_ENABLED;
|
| + const Extension* extension =
|
| + registry->enabled_extensions().GetByID(params->id);
|
| + if (!extension &&
|
| + (extension = registry->disabled_extensions().GetByID(params->id)) !=
|
| + nullptr) {
|
| + state = developer::EXTENSION_STATE_DISABLED;
|
| + } else if (!extension &&
|
| + (extension =
|
| + registry->terminated_extensions().GetByID(params->id)) !=
|
| + nullptr) {
|
| + state = developer::EXTENSION_STATE_TERMINATED;
|
| } else {
|
| - // For live pages, use the full URL.
|
| - view->path = url.spec();
|
| - }
|
| -
|
| - view->render_process_id = render_process_id;
|
| - view->render_view_id = render_view_id;
|
| - view->incognito = incognito;
|
| - view->generated_background_page = generated_background_page;
|
| - return view;
|
| -}
|
| -
|
| -ItemInspectViewList DeveloperPrivateGetItemsInfoFunction::
|
| - GetInspectablePagesForExtension(
|
| - const Extension* extension,
|
| - bool extension_is_enabled) {
|
| - ItemInspectViewList result;
|
| - // Get the extension process's active views.
|
| - ProcessManager* process_manager = ProcessManager::Get(GetProfile());
|
| - GetInspectablePagesForExtensionProcess(
|
| - extension,
|
| - process_manager->GetRenderViewHostsForExtension(extension->id()),
|
| - &result);
|
| -
|
| - // Get app window views.
|
| - GetAppWindowPagesForExtensionProfile(extension, &result);
|
| -
|
| - // Include a link to start the lazy background page, if applicable.
|
| - if (BackgroundInfo::HasLazyBackgroundPage(extension) &&
|
| - extension_is_enabled &&
|
| - !process_manager->GetBackgroundHostForExtension(extension->id())) {
|
| - result.push_back(constructInspectView(
|
| - BackgroundInfo::GetBackgroundURL(extension),
|
| - -1,
|
| - -1,
|
| - false,
|
| - BackgroundInfo::HasGeneratedBackgroundPage(extension)));
|
| - }
|
| -
|
| - ExtensionService* service = GetExtensionService(GetProfile());
|
| - // Repeat for the incognito process, if applicable. Don't try to get
|
| - // app windows for incognito process.
|
| - if (service->profile()->HasOffTheRecordProfile() &&
|
| - IncognitoInfo::IsSplitMode(extension)) {
|
| - process_manager =
|
| - ProcessManager::Get(service->profile()->GetOffTheRecordProfile());
|
| - GetInspectablePagesForExtensionProcess(
|
| - extension,
|
| - process_manager->GetRenderViewHostsForExtension(extension->id()),
|
| - &result);
|
| -
|
| - if (BackgroundInfo::HasLazyBackgroundPage(extension) &&
|
| - extension_is_enabled &&
|
| - !process_manager->GetBackgroundHostForExtension(extension->id())) {
|
| - result.push_back(constructInspectView(
|
| - BackgroundInfo::GetBackgroundURL(extension),
|
| - -1,
|
| - -1,
|
| - false,
|
| - BackgroundInfo::HasGeneratedBackgroundPage(extension)));
|
| - }
|
| + return RespondNow(Error(kNoSuchExtensionError));
|
| }
|
|
|
| - return result;
|
| + return RespondNow(OneArgument(CreateExtensionInfo(
|
| + *extension, state, browser_context())->ToValue().release()));
|
| }
|
|
|
| -bool DeveloperPrivateGetItemsInfoFunction::RunAsync() {
|
| +DeveloperPrivateGetItemsInfoFunction::DeveloperPrivateGetItemsInfoFunction() {}
|
| +DeveloperPrivateGetItemsInfoFunction::~DeveloperPrivateGetItemsInfoFunction() {}
|
| +
|
| +ExtensionFunction::ResponseAction DeveloperPrivateGetItemsInfoFunction::Run() {
|
| scoped_ptr<developer::GetItemsInfo::Params> params(
|
| developer::GetItemsInfo::Params::Create(*args_));
|
| - EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
|
| -
|
| - bool include_disabled = params->include_disabled;
|
| - bool include_terminated = params->include_terminated;
|
| + EXTENSION_FUNCTION_VALIDATE(params);
|
|
|
| ExtensionSet items;
|
| -
|
| - ExtensionRegistry* registry = ExtensionRegistry::Get(GetProfile());
|
| -
|
| + ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context());
|
| items.InsertAll(registry->enabled_extensions());
|
|
|
| - if (include_disabled) {
|
| + if (params->include_disabled)
|
| items.InsertAll(registry->disabled_extensions());
|
| - }
|
| -
|
| - if (include_terminated) {
|
| + 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);
|
| + }
|
| }
|
|
|
| - ExtensionService* service =
|
| - ExtensionSystem::Get(GetProfile())->extension_service();
|
| - std::map<std::string, ExtensionResource> id_to_icon;
|
| - ItemInfoList item_list;
|
| + std::vector<linked_ptr<developer::ExtensionInfo>> list =
|
| + GetExtensionsInfo(browser_context(),
|
| + params->include_disabled,
|
| + params->include_terminated);
|
|
|
| - for (ExtensionSet::const_iterator iter = items.begin(); iter != items.end();
|
| - ++iter) {
|
| - const Extension& item = *iter->get();
|
| + for (const linked_ptr<developer::ExtensionInfo>& info : list)
|
| + item_list_.push_back(developer_private_mangle::MangleExtensionInfo(*info));
|
|
|
| - ExtensionResource item_resource =
|
| - IconsInfo::GetIconResource(&item,
|
| - extension_misc::EXTENSION_ICON_MEDIUM,
|
| - ExtensionIconSet::MATCH_BIGGER);
|
| - id_to_icon[item.id()] = item_resource;
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::FILE,
|
| + FROM_HERE,
|
| + base::Bind(&DeveloperPrivateGetItemsInfoFunction::GetIconsOnFileThread,
|
| + this,
|
| + resource_map));
|
|
|
| - // Don't show component extensions and invisible apps.
|
| - if (ui_util::ShouldNotBeVisible(&item, GetProfile()))
|
| - continue;
|
| + return RespondLater();
|
| +}
|
|
|
| - item_list.push_back(make_linked_ptr<developer::ItemInfo>(
|
| - CreateItemInfo(
|
| - item, service->IsExtensionEnabled(item.id())).release()));
|
| +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::FILE, FROM_HERE,
|
| - base::Bind(&DeveloperPrivateGetItemsInfoFunction::GetIconsOnFileThread,
|
| - this,
|
| - item_list,
|
| - id_to_icon));
|
| -
|
| - return true;
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(&DeveloperPrivateGetItemsInfoFunction::Finish, this));
|
| }
|
|
|
| -DeveloperPrivateGetItemsInfoFunction::~DeveloperPrivateGetItemsInfoFunction() {}
|
| +void DeveloperPrivateGetItemsInfoFunction::Finish() {
|
| + Respond(ArgumentList(developer::GetItemsInfo::Results::Create(item_list_)));
|
| +}
|
|
|
| ExtensionFunction::ResponseAction
|
| DeveloperPrivateAllowFileAccessFunction::Run() {
|
|
|