#include "chrome/browser/extensions/api/management/management_api.h"
-#include <map>
#include <string>
#include <vector>
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/api/management/management_api_constants.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_ui_util.h"
#include "chrome/browser/extensions/extension_uninstall_dialog.h"
+#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/launch_util.h"
+#include "chrome/browser/extensions/window_controller.h"
+#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
-#include "chrome/common/chrome_utility_messages.h"
+#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
#include "chrome/common/extensions/api/management.h"
+#include "chrome/common/extensions/chrome_utility_extensions_messages.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_url_handler.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_source.h"
#include "content/public/browser/utility_process_host.h"
#include "content/public/browser/utility_process_host_client.h"
#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/management_policy.h"
+#include "extensions/browser/uninstall_reason.h"
#include "extensions/common/constants.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_icon_set.h"
#include "extensions/common/manifest_handlers/icons_handler.h"
#include "extensions/common/manifest_handlers/offline_enabled_info.h"
+#include "extensions/common/manifest_handlers/options_page_info.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/url_pattern.h"
-#if !defined(OS_ANDROID)
-#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
-#endif
-
using base::IntToString;
using content::BrowserThread;
using content::UtilityProcessHost;
std::vector<std::string> CreateWarningsList(const Extension* extension) {
std::vector<std::string> warnings_list;
PermissionMessages warnings =
- PermissionsData::GetPermissionMessages(extension);
+ extension->permissions_data()->GetPermissionMessages();
for (PermissionMessages::const_iterator iter = warnings.begin();
iter != warnings.end(); ++iter) {
warnings_list.push_back(base::UTF16ToUTF8(iter->message()));
return warnings_list;
}
+std::vector<management::LaunchType> GetAvailableLaunchTypes(
+ const Extension& extension) {
+ std::vector<management::LaunchType> launch_type_list;
+ if (extension.is_platform_app()) {
+ launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_WINDOW);
+ return launch_type_list;
+ }
+
+ launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB);
+
+#if !defined(OS_MACOSX)
+ launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_WINDOW);
+#endif
+
+ if (!util::IsStreamlinedHostedAppsEnabled()) {
+ launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB);
+ launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_FULL_SCREEN);
+ }
+ return launch_type_list;
+}
+
scoped_ptr<management::ExtensionInfo> CreateExtensionInfo(
const Extension& extension,
ExtensionSystem* system) {
info->offline_enabled = OfflineEnabledInfo::IsOfflineEnabled(&extension);
info->version = extension.VersionString();
info->description = extension.description();
- info->options_url = ManifestURL::GetOptionsPage(&extension).spec();
+ info->options_url = OptionsPageInfo::GetOptionsPage(&extension).spec();
info->homepage_url.reset(new std::string(
ManifestURL::GetHomepageURL(&extension).spec()));
info->may_disable = system->management_policy()->
}
const std::set<std::string> perms =
- extension.GetActivePermissions()->GetAPIsAsStrings();
+ extension.permissions_data()->active_permissions()->GetAPIsAsStrings();
if (!perms.empty()) {
std::set<std::string>::const_iterator perms_iter;
for (perms_iter = perms.begin(); perms_iter != perms.end(); ++perms_iter)
if (!extension.is_hosted_app()) {
// Skip host permissions for hosted apps.
const URLPatternSet host_perms =
- extension.GetActivePermissions()->explicit_hosts();
+ extension.permissions_data()->active_permissions()->explicit_hosts();
if (!host_perms.is_empty()) {
for (URLPatternSet::const_iterator iter = host_perms.begin();
iter != host_perms.end(); ++iter) {
break;
}
+ info->launch_type = management::LAUNCH_TYPE_NONE;
+ if (extension.is_app()) {
+ LaunchType launch_type;
+ if (extension.is_platform_app()) {
+ launch_type = LAUNCH_TYPE_WINDOW;
+ } else {
+ launch_type =
+ GetLaunchType(ExtensionPrefs::Get(service->profile()), &extension);
+ }
+
+ switch (launch_type) {
+ case LAUNCH_TYPE_PINNED:
+ info->launch_type = management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB;
+ break;
+ case LAUNCH_TYPE_REGULAR:
+ info->launch_type = management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB;
+ break;
+ case LAUNCH_TYPE_FULLSCREEN:
+ info->launch_type = management::LAUNCH_TYPE_OPEN_FULL_SCREEN;
+ break;
+ case LAUNCH_TYPE_WINDOW:
+ info->launch_type = management::LAUNCH_TYPE_OPEN_AS_WINDOW;
+ break;
+ case LAUNCH_TYPE_INVALID:
+ case NUM_LAUNCH_TYPES:
+ NOTREACHED();
+ }
+
+ info->available_launch_types.reset(new std::vector<management::LaunchType>(
+ GetAvailableLaunchTypes(extension)));
+ }
+
return info.Pass();
}
void AddExtensionInfo(const ExtensionSet& extensions,
ExtensionSystem* system,
- ExtensionInfoList* extension_list) {
+ ExtensionInfoList* extension_list,
+ content::BrowserContext* context) {
for (ExtensionSet::const_iterator iter = extensions.begin();
iter != extensions.end(); ++iter) {
const Extension& extension = *iter->get();
- if (extension.ShouldNotBeVisible())
+ if (ui_util::ShouldNotBeVisible(&extension, context))
continue; // Skip built-in extensions/apps.
extension_list->push_back(make_linked_ptr<management::ExtensionInfo>(
}
}
-} // namespace
+} // namespace
ExtensionService* ManagementFunction::service() {
- return GetProfile()->GetExtensionService();
+ return ExtensionSystem::Get(GetProfile())->extension_service();
}
ExtensionService* AsyncManagementFunction::service() {
- return GetProfile()->GetExtensionService();
+ return ExtensionSystem::Get(GetProfile())->extension_service();
}
bool ManagementGetAllFunction::RunSync() {
ExtensionRegistry* registry = ExtensionRegistry::Get(GetProfile());
ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
- AddExtensionInfo(registry->enabled_extensions(), system, &extensions);
- AddExtensionInfo(registry->disabled_extensions(), system, &extensions);
- AddExtensionInfo(registry->terminated_extensions(), system, &extensions);
+ AddExtensionInfo(registry->enabled_extensions(),
+ system, &extensions, browser_context());
+ AddExtensionInfo(registry->disabled_extensions(),
+ system, &extensions, browser_context());
+ AddExtensionInfo(registry->terminated_extensions(),
+ system, &extensions, browser_context());
results_ = management::GetAll::Results::Create(extensions);
return true;
return true;
}
+bool ManagementGetSelfFunction::RunSync() {
+ scoped_ptr<management::ExtensionInfo> info =
+ CreateExtensionInfo(*extension_, ExtensionSystem::Get(GetProfile()));
+ results_ = management::Get::Results::Create(*info);
+
+ return true;
+}
+
bool ManagementGetPermissionWarningsByIdFunction::RunSync() {
scoped_ptr<management::GetPermissionWarningsById::Params> params(
management::GetPermissionWarningsById::Params::Create(*args_));
GetLaunchContainer(ExtensionPrefs::Get(GetProfile()), extension);
OpenApplication(AppLaunchParams(
GetProfile(), extension, launch_container, NEW_FOREGROUND_TAB));
-#if !defined(OS_ANDROID)
CoreAppLauncherHandler::RecordAppLaunchType(
extension_misc::APP_LAUNCH_EXTENSION_API,
extension->GetType());
-#endif
return true;
}
extension_id_ = params->id;
- const Extension* extension = service()->GetInstalledExtension(extension_id_);
- if (!extension || extension->ShouldNotBeVisible()) {
+ const Extension* extension =
+ ExtensionRegistry::Get(GetProfile())
+ ->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING);
+ if (!extension || ui_util::ShouldNotBeVisible(extension, browser_context())) {
error_ = ErrorUtils::FormatErrorMessage(
keys::kNoExtensionError, extension_id_);
return false;
error_ = keys::kGestureNeededForEscalationError;
return false;
}
- AddRef(); // Matched in InstallUIProceed/InstallUIAbort
+ AddRef(); // Matched in InstallUIProceed/InstallUIAbort
install_prompt_.reset(
new ExtensionInstallPrompt(GetAssociatedWebContents()));
install_prompt_->ConfirmReEnable(this, extension);
bool show_confirm_dialog) {
extension_id_ = target_extension_id;
const Extension* target_extension =
- service()->GetExtensionById(extension_id_, true);
- if (!target_extension || target_extension->ShouldNotBeVisible()) {
+ extensions::ExtensionRegistry::Get(browser_context())->
+ GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING);
+ if (!target_extension ||
+ ui_util::ShouldNotBeVisible(target_extension, browser_context())) {
error_ = ErrorUtils::FormatErrorMessage(
keys::kNoExtensionError, extension_id_);
return false;
if (auto_confirm_for_test == DO_NOT_SKIP) {
if (show_confirm_dialog) {
- AddRef(); // Balanced in ExtensionUninstallAccepted/Canceled
+ AddRef(); // Balanced in ExtensionUninstallAccepted/Canceled
+ extensions::WindowController* controller = GetExtensionWindowController();
extension_uninstall_dialog_.reset(ExtensionUninstallDialog::Create(
- GetProfile(), GetCurrentBrowser(), this));
+ GetProfile(),
+ controller ? controller->window()->GetNativeWindow() : NULL,
+ this));
if (extension_id() != target_extension_id) {
extension_uninstall_dialog_->ConfirmProgrammaticUninstall(
- target_extension, GetExtension());
+ target_extension, extension());
} else {
// If this is a self uninstall, show the generic uninstall dialog.
extension_uninstall_dialog_->ConfirmUninstall(target_extension);
extension_id_);
SendResponse(false);
} else {
- bool success =
- service()->UninstallExtension(extension_id_,
- false, /* external uninstall */
- NULL);
+ bool success = service()->UninstallExtension(
+ extension_id_,
+ extensions::UNINSTALL_REASON_MANAGEMENT_API,
+ base::Bind(&base::DoNothing),
+ NULL);
// TODO set error_ if !success
SendResponse(success);
keys::kUninstallCanceledError, extension_id_);
SendResponse(false);
}
-
}
void ManagementUninstallFunctionBase::ExtensionUninstallAccepted() {
bool ManagementUninstallFunction::RunAsync() {
scoped_ptr<management::Uninstall::Params> params(
management::Uninstall::Params::Create(*args_));
- EXTENSION_FUNCTION_VALIDATE(extension_);
+ EXTENSION_FUNCTION_VALIDATE(extension_.get());
EXTENSION_FUNCTION_VALIDATE(params.get());
bool show_confirm_dialog = true;
return true;
}
-ManagementEventRouter::ManagementEventRouter(Profile* profile)
- : profile_(profile) {
- int types[] = {chrome::NOTIFICATION_EXTENSION_INSTALLED,
- chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
- chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
- chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED};
+bool ManagementSetLaunchTypeFunction::RunSync() {
+ if (!user_gesture()) {
+ error_ = keys::kGestureNeededForSetLaunchTypeError;
+ return false;
+ }
+
+ scoped_ptr<management::SetLaunchType::Params> params(
+ management::SetLaunchType::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+ const Extension* extension = service()->GetExtensionById(params->id, true);
+ if (!extension) {
+ error_ =
+ ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id);
+ return false;
+ }
- CHECK(registrar_.IsEmpty());
- for (size_t i = 0; i < arraysize(types); i++) {
- registrar_.Add(this,
- types[i],
- content::Source<Profile>(profile_));
+ if (!extension->is_app()) {
+ error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, params->id);
+ return false;
}
-}
-ManagementEventRouter::~ManagementEventRouter() {}
+ std::vector<management::LaunchType> available_launch_types =
+ GetAvailableLaunchTypes(*extension);
+
+ management::LaunchType app_launch_type = params->launch_type;
+ if (std::find(available_launch_types.begin(),
+ available_launch_types.end(),
+ app_launch_type) == available_launch_types.end()) {
+ error_ = keys::kLaunchTypeNotAvailableError;
+ return false;
+ }
-void ManagementEventRouter::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- const char* event_name = NULL;
- const Extension* extension = NULL;
- Profile* profile = content::Source<Profile>(source).ptr();
- CHECK(profile);
- CHECK(profile_->IsSameProfile(profile));
-
- switch (type) {
- case chrome::NOTIFICATION_EXTENSION_INSTALLED:
- event_name = management::OnInstalled::kEventName;
- extension =
- content::Details<const InstalledExtensionInfo>(details)->extension;
+ LaunchType launch_type = LAUNCH_TYPE_DEFAULT;
+ switch (app_launch_type) {
+ case management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB:
+ launch_type = LAUNCH_TYPE_PINNED;
break;
- case chrome::NOTIFICATION_EXTENSION_UNINSTALLED:
- event_name = management::OnUninstalled::kEventName;
- extension = content::Details<const Extension>(details).ptr();
+ case management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB:
+ launch_type = LAUNCH_TYPE_REGULAR;
break;
- case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED:
- event_name = management::OnEnabled::kEventName;
- extension = content::Details<const Extension>(details).ptr();
+ case management::LAUNCH_TYPE_OPEN_FULL_SCREEN:
+ launch_type = LAUNCH_TYPE_FULLSCREEN;
break;
- case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED:
- event_name = management::OnDisabled::kEventName;
- extension =
- content::Details<const UnloadedExtensionInfo>(details)->extension;
+ case management::LAUNCH_TYPE_OPEN_AS_WINDOW:
+ launch_type = LAUNCH_TYPE_WINDOW;
break;
- default:
+ case management::LAUNCH_TYPE_NONE:
NOTREACHED();
- return;
}
- DCHECK(event_name);
- DCHECK(extension);
- if (extension->ShouldNotBeVisible())
- return; // Don't dispatch events for built-in extensions.
+ SetLaunchType(service(), params->id, launch_type);
+
+ return true;
+}
+
+ManagementGenerateAppForLinkFunction::ManagementGenerateAppForLinkFunction() {
+}
+
+ManagementGenerateAppForLinkFunction::~ManagementGenerateAppForLinkFunction() {
+}
+
+void ManagementGenerateAppForLinkFunction::FinishCreateBookmarkApp(
+ const Extension* extension,
+ const WebApplicationInfo& web_app_info) {
+ if (extension) {
+ scoped_ptr<management::ExtensionInfo> info =
+ CreateExtensionInfo(*extension, ExtensionSystem::Get(GetProfile()));
+ results_ = management::GenerateAppForLink::Results::Create(*info);
+
+ SendResponse(true);
+ Release();
+ } else {
+ error_ = keys::kGenerateAppForLinkInstallError;
+ SendResponse(false);
+ Release();
+ }
+}
+
+void ManagementGenerateAppForLinkFunction::OnFaviconForApp(
+ const favicon_base::FaviconImageResult& image_result) {
+ WebApplicationInfo web_app;
+ web_app.title = base::UTF8ToUTF16(title_);
+ web_app.app_url = launch_url_;
+
+ if (!image_result.image.IsEmpty()) {
+ WebApplicationInfo::IconInfo icon;
+ icon.data = image_result.image.AsBitmap();
+ icon.width = icon.data.width();
+ icon.height = icon.data.height();
+ web_app.icons.push_back(icon);
+ }
+
+ bookmark_app_helper_.reset(new BookmarkAppHelper(service(), web_app, NULL));
+ bookmark_app_helper_->Create(base::Bind(
+ &ManagementGenerateAppForLinkFunction::FinishCreateBookmarkApp, this));
+}
+
+bool ManagementGenerateAppForLinkFunction::RunAsync() {
+ if (!user_gesture()) {
+ error_ = keys::kGestureNeededForGenerateAppForLinkError;
+ return false;
+ }
+
+ scoped_ptr<management::GenerateAppForLink::Params> params(
+ management::GenerateAppForLink::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+
+ GURL launch_url(params->url);
+ if (!launch_url.is_valid() || !launch_url.SchemeIsHTTPOrHTTPS()) {
+ error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidURLError,
+ params->url);
+ return false;
+ }
+
+ if (params->title.empty()) {
+ error_ = keys::kEmptyTitleError;
+ return false;
+ }
+
+ FaviconService* favicon_service =
+ FaviconServiceFactory::GetForProfile(GetProfile(),
+ Profile::EXPLICIT_ACCESS);
+ DCHECK(favicon_service);
+
+ title_ = params->title;
+ launch_url_ = launch_url;
+
+ favicon_service->GetFaviconImageForPageURL(
+ launch_url,
+ base::Bind(&ManagementGenerateAppForLinkFunction::OnFaviconForApp, this),
+ &cancelable_task_tracker_);
+
+ // Matched with a Release() in OnExtensionLoaded().
+ AddRef();
+
+ // Response is sent async in OnExtensionLoaded().
+ return true;
+}
+
+ManagementEventRouter::ManagementEventRouter(content::BrowserContext* context)
+ : browser_context_(context), extension_registry_observer_(this) {
+ extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
+}
+
+ManagementEventRouter::~ManagementEventRouter() {}
+
+void ManagementEventRouter::OnExtensionLoaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension) {
+ BroadcastEvent(extension, management::OnEnabled::kEventName);
+}
+
+void ManagementEventRouter::OnExtensionUnloaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionInfo::Reason reason) {
+ BroadcastEvent(extension, management::OnDisabled::kEventName);
+}
+
+void ManagementEventRouter::OnExtensionInstalled(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ bool is_update) {
+ BroadcastEvent(extension, management::OnInstalled::kEventName);
+}
+
+void ManagementEventRouter::OnExtensionUninstalled(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ extensions::UninstallReason reason) {
+ BroadcastEvent(extension, management::OnUninstalled::kEventName);
+}
+void ManagementEventRouter::BroadcastEvent(const Extension* extension,
+ const char* event_name) {
+ if (ui_util::ShouldNotBeVisible(extension, browser_context_))
+ return; // Don't dispatch events for built-in extenions.
scoped_ptr<base::ListValue> args(new base::ListValue());
if (event_name == management::OnUninstalled::kEventName) {
args->Append(new base::StringValue(extension->id()));
} else {
- scoped_ptr<management::ExtensionInfo> info = CreateExtensionInfo(
- *extension, ExtensionSystem::Get(profile));
+ scoped_ptr<management::ExtensionInfo> info =
+ CreateExtensionInfo(*extension, ExtensionSystem::Get(browser_context_));
args->Append(info->ToValue().release());
}
- scoped_ptr<Event> event(new Event(event_name, args.Pass()));
- EventRouter::Get(profile)->BroadcastEvent(event.Pass());
+ EventRouter::Get(browser_context_)
+ ->BroadcastEvent(scoped_ptr<Event>(new Event(event_name, args.Pass())));
}
ManagementAPI::ManagementAPI(content::BrowserContext* context)
}
void ManagementAPI::OnListenerAdded(const EventListenerInfo& details) {
- management_event_router_.reset(
- new ManagementEventRouter(Profile::FromBrowserContext(browser_context_)));
+ management_event_router_.reset(new ManagementEventRouter(browser_context_));
EventRouter::Get(browser_context_)->UnregisterObserver(this);
}