15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/management/management_api.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/logging.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/management/management_api_constants.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/extension_ui_util.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_uninstall_dialog.h"
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/extensions/extension_util.h"
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/extensions/launch_util.h"
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/extensions/window_controller.h"
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/favicon/favicon_service_factory.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h"
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/extensions/application_launch.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/api/management.h"
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/extensions/chrome_utility_extensions_messages.h"
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h"
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/utility_process_host.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/utility_process_host_client.h"
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h"
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_prefs.h"
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/management_policy.h"
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/uninstall_reason.h"
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/constants.h"
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/error_utils.h"
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/extension_icon_set.h"
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/manifest_handlers/icons_handler.h"
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/offline_enabled_info.h"
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/manifest_handlers/options_page_info.h"
561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "extensions/common/permissions/permission_set.h"
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/url_pattern.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::IntToString;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::UtilityProcessHost;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::UtilityProcessHostClient;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace keys = extension_management_api_constants;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace management = api::management;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::vector<linked_ptr<management::ExtensionInfo> > ExtensionInfoList;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::vector<linked_ptr<management::IconInfo> > IconInfoList;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum AutoConfirmForTest {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DO_NOT_SKIP = 0,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PROCEED,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ABORT
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutoConfirmForTest auto_confirm_for_test = DO_NOT_SKIP;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<std::string> CreateWarningsList(const Extension* extension) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> warnings_list;
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PermissionMessages warnings =
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      extension->permissions_data()->GetPermissionMessages();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (PermissionMessages::const_iterator iter = warnings.begin();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != warnings.end(); ++iter) {
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    warnings_list.push_back(base::UTF16ToUTF8(iter->message()));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return warnings_list;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::vector<management::LaunchType> GetAvailableLaunchTypes(
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const Extension& extension) {
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<management::LaunchType> launch_type_list;
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (extension.is_platform_app()) {
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_WINDOW);
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return launch_type_list;
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB);
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if !defined(OS_MACOSX)
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_WINDOW);
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!util::IsStreamlinedHostedAppsEnabled()) {
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB);
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_FULL_SCREEN);
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return launch_type_list;
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<management::ExtensionInfo> CreateExtensionInfo(
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Extension& extension,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionSystem* system) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<management::ExtensionInfo> info(new management::ExtensionInfo());
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionService* service = system->extension_service();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->id = extension.id();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->name = extension.name();
125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  info->short_name = extension.short_name();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->enabled = service->IsExtensionEnabled(info->id);
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  info->offline_enabled = OfflineEnabledInfo::IsOfflineEnabled(&extension);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->version = extension.VersionString();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->description = extension.description();
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  info->options_url = OptionsPageInfo::GetOptionsPage(&extension).spec();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->homepage_url.reset(new std::string(
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ManifestURL::GetHomepageURL(&extension).spec()));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->may_disable = system->management_policy()->
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UserMayModifySettings(&extension, NULL);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->is_app = extension.is_app();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (info->is_app) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (extension.is_legacy_packaged_app())
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info->type = management::ExtensionInfo::TYPE_LEGACY_PACKAGED_APP;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (extension.is_hosted_app())
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info->type = management::ExtensionInfo::TYPE_HOSTED_APP;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info->type = management::ExtensionInfo::TYPE_PACKAGED_APP;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (extension.is_theme()) {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info->type = management::ExtensionInfo::TYPE_THEME;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info->type = management::ExtensionInfo::TYPE_EXTENSION;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (info->enabled) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->disabled_reason = management::ExtensionInfo::DISABLED_REASON_NONE;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ExtensionPrefs* prefs = ExtensionPrefs::Get(service->profile());
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (prefs->DidExtensionEscalatePermissions(extension.id())) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info->disabled_reason =
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          management::ExtensionInfo::DISABLED_REASON_PERMISSIONS_INCREASE;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info->disabled_reason =
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          management::ExtensionInfo::DISABLED_REASON_UNKNOWN;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!ManifestURL::GetUpdateURL(&extension).is_empty()) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->update_url.reset(new std::string(
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ManifestURL::GetUpdateURL(&extension).spec()));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension.is_app()) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->app_launch_url.reset(new std::string(
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        AppLaunchInfo::GetFullLaunchURL(&extension).spec()));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ExtensionIconSet::IconMap& icons =
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IconsInfo::GetIcons(&extension).map();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!icons.empty()) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->icons.reset(new IconInfoList());
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionIconSet::IconMap::const_iterator icon_iter;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (icon_iter = icons.begin(); icon_iter != icons.end(); ++icon_iter) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      management::IconInfo* icon_info = new management::IconInfo();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icon_info->size = icon_iter->first;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL url = ExtensionIconSource::GetIconURL(
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &extension, icon_info->size, ExtensionIconSet::MATCH_EXACTLY, false,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          NULL);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icon_info->url = url.spec();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info->icons->push_back(make_linked_ptr<management::IconInfo>(icon_info));
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::set<std::string> perms =
18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      extension.permissions_data()->active_permissions()->GetAPIsAsStrings();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!perms.empty()) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::set<std::string>::const_iterator perms_iter;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (perms_iter = perms.begin(); perms_iter != perms.end(); ++perms_iter)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info->permissions.push_back(*perms_iter);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension.is_hosted_app()) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Skip host permissions for hosted apps.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const URLPatternSet host_perms =
19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        extension.permissions_data()->active_permissions()->explicit_hosts();
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!host_perms.is_empty()) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (URLPatternSet::const_iterator iter = host_perms.begin();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           iter != host_perms.end(); ++iter) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        info->host_permissions.push_back(iter->GetAsString());
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (extension.location()) {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Manifest::INTERNAL:
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info->install_type = management::ExtensionInfo::INSTALL_TYPE_NORMAL;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Manifest::UNPACKED:
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Manifest::COMMAND_LINE:
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info->install_type = management::ExtensionInfo::INSTALL_TYPE_DEVELOPMENT;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Manifest::EXTERNAL_PREF:
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Manifest::EXTERNAL_REGISTRY:
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Manifest::EXTERNAL_PREF_DOWNLOAD:
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info->install_type = management::ExtensionInfo::INSTALL_TYPE_SIDELOAD;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case Manifest::EXTERNAL_POLICY:
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Manifest::EXTERNAL_POLICY_DOWNLOAD:
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info->install_type = management::ExtensionInfo::INSTALL_TYPE_ADMIN;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case Manifest::NUM_LOCATIONS:
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      NOTREACHED();
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case Manifest::INVALID_LOCATION:
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case Manifest::COMPONENT:
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case Manifest::EXTERNAL_COMPONENT:
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info->install_type = management::ExtensionInfo::INSTALL_TYPE_OTHER;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  info->launch_type = management::LAUNCH_TYPE_NONE;
235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (extension.is_app()) {
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LaunchType launch_type;
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (extension.is_platform_app()) {
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      launch_type = LAUNCH_TYPE_WINDOW;
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      launch_type =
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          GetLaunchType(ExtensionPrefs::Get(service->profile()), &extension);
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    switch (launch_type) {
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case LAUNCH_TYPE_PINNED:
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        info->launch_type = management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB;
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case LAUNCH_TYPE_REGULAR:
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        info->launch_type = management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB;
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case LAUNCH_TYPE_FULLSCREEN:
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        info->launch_type = management::LAUNCH_TYPE_OPEN_FULL_SCREEN;
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case LAUNCH_TYPE_WINDOW:
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        info->launch_type = management::LAUNCH_TYPE_OPEN_AS_WINDOW;
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case LAUNCH_TYPE_INVALID:
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case NUM_LAUNCH_TYPES:
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        NOTREACHED();
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    info->available_launch_types.reset(new std::vector<management::LaunchType>(
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        GetAvailableLaunchTypes(extension)));
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return info.Pass();
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddExtensionInfo(const ExtensionSet& extensions,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ExtensionSystem* system,
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            ExtensionInfoList* extension_list,
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            content::BrowserContext* context) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ExtensionSet::const_iterator iter = extensions.begin();
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions.end(); ++iter) {
2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const Extension& extension = *iter->get();
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (ui_util::ShouldNotBeVisible(&extension, context))
2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      continue;  // Skip built-in extensions/apps.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_list->push_back(make_linked_ptr<management::ExtensionInfo>(
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CreateExtensionInfo(extension, system).release()));
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionService* ManagementFunction::service() {
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ExtensionSystem::Get(GetProfile())->extension_service();
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionService* AsyncManagementFunction::service() {
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ExtensionSystem::Get(GetProfile())->extension_service();
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ManagementGetAllFunction::RunSync() {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionInfoList extensions;
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionRegistry* registry = ExtensionRegistry::Get(GetProfile());
2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AddExtensionInfo(registry->enabled_extensions(),
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   system, &extensions, browser_context());
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AddExtensionInfo(registry->disabled_extensions(),
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   system, &extensions, browser_context());
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AddExtensionInfo(registry->terminated_extensions(),
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   system, &extensions, browser_context());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results_ = management::GetAll::Results::Create(extensions);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ManagementGetFunction::RunSync() {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<management::Get::Params> params(
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      management::Get::Params::Create(*args_));
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* extension = service()->GetExtensionById(params->id, true);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension) {
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     params->id);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<management::ExtensionInfo> info =
3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      CreateExtensionInfo(*extension, ExtensionSystem::Get(GetProfile()));
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results_ = management::Get::Results::Create(*info);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ManagementGetSelfFunction::RunSync() {
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<management::ExtensionInfo> info =
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      CreateExtensionInfo(*extension_, ExtensionSystem::Get(GetProfile()));
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  results_ = management::Get::Results::Create(*info);
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ManagementGetPermissionWarningsByIdFunction::RunSync() {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<management::GetPermissionWarningsById::Params> params(
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      management::GetPermissionWarningsById::Params::Create(*args_));
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* extension = service()->GetExtensionById(params->id, true);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension) {
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError,
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     params->id);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> warnings = CreateWarningsList(extension);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results_ = management::GetPermissionWarningsById::Results::Create(warnings);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class helps ManagementGetPermissionWarningsByManifestFunction manage
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sending manifest JSON strings to the utility process for parsing.
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SafeManifestJSONParser : public UtilityProcessHostClient {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SafeManifestJSONParser(
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ManagementGetPermissionWarningsByManifestFunction* client,
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& manifest)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : client_(client),
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        manifest_(manifest) {}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Start() {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::IO,
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&SafeManifestJSONParser::StartWorkOnIOThread, this));
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartWorkOnIOThread() {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UtilityProcessHost* host = UtilityProcessHost::Create(
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        this, base::MessageLoopProxy::current().get());
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host->Send(new ChromeUtilityMsg_ParseJSON(manifest_));
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool handled = true;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_BEGIN_MESSAGE_MAP(SafeManifestJSONParser, message)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          OnJSONParseSucceeded)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed,
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          OnJSONParseFailed)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IPC_MESSAGE_UNHANDLED(handled = false)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_END_MESSAGE_MAP()
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return handled;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void OnJSONParseSucceeded(const base::ListValue& wrapper) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::Value* value = NULL;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(wrapper.Get(0, &value));
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (value->IsType(base::Value::TYPE_DICTIONARY))
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parsed_manifest_.reset(
400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          static_cast<const base::DictionaryValue*>(value)->DeepCopy());
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_ = keys::kManifestParseError;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::UI,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&SafeManifestJSONParser::ReportResultFromUIThread, this));
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnJSONParseFailed(const std::string& error) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_ = error;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::UI,
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&SafeManifestJSONParser::ReportResultFromUIThread, this));
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ReportResultFromUIThread() {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (error_.empty() && parsed_manifest_.get())
4221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      client_->OnParseSuccess(parsed_manifest_.Pass());
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_->OnParseFailure(error_);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~SafeManifestJSONParser() {}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The client who we'll report results back to.
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ManagementGetPermissionWarningsByManifestFunction* client_;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Data to parse.
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string manifest_;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Results of parsing.
437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<base::DictionaryValue> parsed_manifest_;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error_;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
444010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ManagementGetPermissionWarningsByManifestFunction::RunAsync() {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<management::GetPermissionWarningsByManifest::Params> params(
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      management::GetPermissionWarningsByManifest::Params::Create(*args_));
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SafeManifestJSONParser> parser =
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new SafeManifestJSONParser(this, params->manifest_str);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parser->Start();
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Matched with a Release() in OnParseSuccess/Failure().
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRef();
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Response is sent async in OnParseSuccess/Failure().
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ManagementGetPermissionWarningsByManifestFunction::OnParseSuccess(
4611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> parsed_manifest) {
4621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  CHECK(parsed_manifest.get());
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> extension = Extension::Create(
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(), Manifest::INVALID_LOCATION, *parsed_manifest,
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Extension::NO_FLAGS, &error_);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension.get()) {
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnParseFailure(keys::kExtensionCreateError);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::vector<std::string> warnings = CreateWarningsList(extension.get());
473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  results_ =
474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      management::GetPermissionWarningsByManifest::Results::Create(warnings);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(true);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
477010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Matched with AddRef() in RunAsync().
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ManagementGetPermissionWarningsByManifestFunction::OnParseFailure(
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& error) {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error_ = error;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(false);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
486010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Matched with AddRef() in RunAsync().
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ManagementLaunchAppFunction::RunSync() {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<management::LaunchApp::Params> params(
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      management::LaunchApp::Params::Create(*args_));
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* extension = service()->GetExtensionById(params->id, true);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension) {
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     params->id);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension->is_app()) {
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     params->id);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Look at prefs to find the right launch container.
507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If the user has not set a preference, the default launch value will be
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // returned.
509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LaunchContainer launch_container =
510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetLaunchContainer(ExtensionPrefs::Get(GetProfile()), extension);
5111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  OpenApplication(AppLaunchParams(
5121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      GetProfile(), extension, launch_container, NEW_FOREGROUND_TAB));
513558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  CoreAppLauncherHandler::RecordAppLaunchType(
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_misc::APP_LAUNCH_EXTENSION_API,
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension->GetType());
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ManagementSetEnabledFunction::ManagementSetEnabledFunction() {
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ManagementSetEnabledFunction::~ManagementSetEnabledFunction() {
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
526010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ManagementSetEnabledFunction::RunAsync() {
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<management::SetEnabled::Params> params(
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      management::SetEnabled::Params::Create(*args_));
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_id_ = params->id;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const Extension* extension =
534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ExtensionRegistry::Get(GetProfile())
535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING);
536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!extension || ui_util::ShouldNotBeVisible(extension, browser_context())) {
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keys::kNoExtensionError, extension_id_);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const ManagementPolicy* policy =
5431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ExtensionSystem::Get(GetProfile())->management_policy();
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!policy->UserMayModifySettings(extension, NULL) ||
545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      (!params->enabled && policy->MustRemainEnabled(extension, NULL)) ||
546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      (params->enabled && policy->MustRemainDisabled(extension, NULL, NULL))) {
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keys::kUserCantModifyError, extension_id_);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool currently_enabled = service()->IsExtensionEnabled(extension_id_);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!currently_enabled && params->enabled) {
555a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ExtensionPrefs* prefs = ExtensionPrefs::Get(GetProfile());
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (prefs->DidExtensionEscalatePermissions(extension_id_)) {
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!user_gesture()) {
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        error_ = keys::kGestureNeededForEscalationError;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
561116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AddRef();  // Matched in InstallUIProceed/InstallUIAbort
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      install_prompt_.reset(
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          new ExtensionInstallPrompt(GetAssociatedWebContents()));
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      install_prompt_->ConfirmReEnable(this, extension);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service()->EnableExtension(extension_id_);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (currently_enabled && !params->enabled) {
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service()->DisableExtension(extension_id_, Extension::DISABLE_USER_ACTION);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI,
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ManagementSetEnabledFunction::SendResponse, this, true));
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ManagementSetEnabledFunction::InstallUIProceed() {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service()->EnableExtension(extension_id_);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(true);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ManagementSetEnabledFunction::InstallUIAbort(bool user_initiated) {
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error_ = keys::kUserDidNotReEnableError;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(false);
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ManagementUninstallFunctionBase::ManagementUninstallFunctionBase() {
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ManagementUninstallFunctionBase::~ManagementUninstallFunctionBase() {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ManagementUninstallFunctionBase::Uninstall(
599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& target_extension_id,
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool show_confirm_dialog) {
601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  extension_id_ = target_extension_id;
602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const Extension* target_extension =
6031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      extensions::ExtensionRegistry::Get(browser_context())->
6041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING);
605cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!target_extension ||
606cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ui_util::ShouldNotBeVisible(target_extension, browser_context())) {
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keys::kNoExtensionError, extension_id_);
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!ExtensionSystem::Get(GetProfile())
6131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)           ->management_policy()
614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           ->UserMayModifySettings(target_extension, NULL)) {
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keys::kUserCantModifyError, extension_id_);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (auto_confirm_for_test == DO_NOT_SKIP) {
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (show_confirm_dialog) {
622116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AddRef();  // Balanced in ExtensionUninstallAccepted/Canceled
6235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extensions::WindowController* controller = GetExtensionWindowController();
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension_uninstall_dialog_.reset(ExtensionUninstallDialog::Create(
6255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          GetProfile(),
6265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          controller ? controller->window()->GetNativeWindow() : NULL,
6275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          this));
628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (extension_id() != target_extension_id) {
629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        extension_uninstall_dialog_->ConfirmProgrammaticUninstall(
6305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            target_extension, extension());
631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      } else {
632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        // If this is a self uninstall, show the generic uninstall dialog.
633a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        extension_uninstall_dialog_->ConfirmUninstall(target_extension);
634a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Finish(true);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Finish(auto_confirm_for_test == PROCEED);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ManagementUninstallFunctionBase::SetAutoConfirmForTest(
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool should_proceed) {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auto_confirm_for_test = should_proceed ? PROCEED : ABORT;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ManagementUninstallFunctionBase::Finish(bool should_uninstall) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (should_uninstall) {
653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // The extension can be uninstalled in another window while the UI was
654cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // showing. Do nothing in that case.
655cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ExtensionRegistry* registry = ExtensionRegistry::Get(GetProfile());
656cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const Extension* extension = registry->GetExtensionById(
657cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        extension_id_, ExtensionRegistry::EVERYTHING);
658cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!extension) {
659cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError,
660cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                              extension_id_);
661cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      SendResponse(false);
662cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
663116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      bool success = service()->UninstallExtension(
664116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          extension_id_,
6655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          extensions::UNINSTALL_REASON_MANAGEMENT_API,
6665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          base::Bind(&base::DoNothing),
667116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          NULL);
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
669cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // TODO set error_ if !success
670cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      SendResponse(success);
671cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keys::kUninstallCanceledError, extension_id_);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SendResponse(false);
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ManagementUninstallFunctionBase::ExtensionUninstallAccepted() {
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Finish(true);
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ManagementUninstallFunctionBase::ExtensionUninstallCanceled() {
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Finish(false);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ManagementUninstallFunction::ManagementUninstallFunction() {
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ManagementUninstallFunction::~ManagementUninstallFunction() {
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
695010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ManagementUninstallFunction::RunAsync() {
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<management::Uninstall::Params> params(
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      management::Uninstall::Params::Create(*args_));
6981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXTENSION_FUNCTION_VALIDATE(extension_.get());
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool show_confirm_dialog = true;
7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // By default confirmation dialog isn't shown when uninstalling self, but this
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // can be overridden with showConfirmDialog.
7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (params->id == extension_->id()) {
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    show_confirm_dialog = params->options.get() &&
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          params->options->show_confirm_dialog.get() &&
7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          *params->options->show_confirm_dialog;
7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
7095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (show_confirm_dialog && !user_gesture()) {
7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    error_ = keys::kGestureNeededForUninstallError;
7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Uninstall(params->id, show_confirm_dialog);
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ManagementUninstallSelfFunction::ManagementUninstallSelfFunction() {
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ManagementUninstallSelfFunction::~ManagementUninstallSelfFunction() {
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ManagementUninstallSelfFunction::RunAsync() {
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<management::UninstallSelf::Params> params(
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      management::UninstallSelf::Params::Create(*args_));
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool show_confirm_dialog = false;
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (params->options.get() && params->options->show_confirm_dialog.get())
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    show_confirm_dialog = *params->options->show_confirm_dialog;
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Uninstall(extension_->id(), show_confirm_dialog);
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
733010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ManagementCreateAppShortcutFunction::ManagementCreateAppShortcutFunction() {
734010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
735010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
736010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ManagementCreateAppShortcutFunction::~ManagementCreateAppShortcutFunction() {
737010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
738010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
739010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static
740010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(
741010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bool should_proceed) {
742010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  auto_confirm_for_test = should_proceed ? PROCEED : ABORT;
743010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
744010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
745010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ManagementCreateAppShortcutFunction::OnCloseShortcutPrompt(bool created) {
746010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!created)
747010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    error_ = keys::kCreateShortcutCanceledError;
748010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  SendResponse(created);
749010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Release();
750010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
751010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
752010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ManagementCreateAppShortcutFunction::RunAsync() {
753010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!user_gesture()) {
754010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    error_ = keys::kGestureNeededForCreateAppShortcutError;
755010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
756010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
757010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
758010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<management::CreateAppShortcut::Params> params(
759010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      management::CreateAppShortcut::Params::Create(*args_));
760010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
761010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const Extension* extension = service()->GetExtensionById(params->id, true);
762010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!extension) {
763010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError,
764010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                            params->id);
765010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
766010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
767010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
768010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!extension->is_app()) {
769010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, params->id);
770010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
771010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
772010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
773010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(OS_MACOSX)
774010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!extension->is_platform_app()) {
775010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    error_ = keys::kCreateOnlyPackagedAppShortcutMac;
776010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
777010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
778010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif
779010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
780010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Browser* browser = chrome::FindBrowserWithProfile(
781010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      GetProfile(), chrome::HOST_DESKTOP_TYPE_NATIVE);
782010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!browser) {
783010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Shouldn't happen if we have user gesture.
784010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    error_ = keys::kNoBrowserToCreateShortcut;
785010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
786010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
787010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
788010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Matched with a Release() in OnCloseShortcutPrompt().
789010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  AddRef();
790010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
791010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (auto_confirm_for_test == DO_NOT_SKIP) {
792010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    chrome::ShowCreateChromeAppShortcutsDialog(
793010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        browser->window()->GetNativeWindow(), browser->profile(), extension,
794010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        base::Bind(&ManagementCreateAppShortcutFunction::OnCloseShortcutPrompt,
795010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           this));
796010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  } else {
797010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    OnCloseShortcutPrompt(auto_confirm_for_test == PROCEED);
798010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
799010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
800010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Response is sent async in OnCloseShortcutPrompt().
801010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;
802010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
803010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
804cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ManagementSetLaunchTypeFunction::RunSync() {
805cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!user_gesture()) {
806cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error_ = keys::kGestureNeededForSetLaunchTypeError;
807cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
808cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
809cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
810cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<management::SetLaunchType::Params> params(
811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      management::SetLaunchType::Params::Create(*args_));
812cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
813cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const Extension* extension = service()->GetExtensionById(params->id, true);
814cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!extension) {
815cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error_ =
816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id);
817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
818cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
819cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
820cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!extension->is_app()) {
821cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, params->id);
822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
823cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
824cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
825cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<management::LaunchType> available_launch_types =
826cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GetAvailableLaunchTypes(*extension);
827cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
828cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  management::LaunchType app_launch_type = params->launch_type;
829cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (std::find(available_launch_types.begin(),
830cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                available_launch_types.end(),
831cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                app_launch_type) == available_launch_types.end()) {
832cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error_ = keys::kLaunchTypeNotAvailableError;
833cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
834cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
835cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
836cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  LaunchType launch_type = LAUNCH_TYPE_DEFAULT;
837cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  switch (app_launch_type) {
838cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB:
839cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      launch_type = LAUNCH_TYPE_PINNED;
840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
841cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB:
842cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      launch_type = LAUNCH_TYPE_REGULAR;
843cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
844cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case management::LAUNCH_TYPE_OPEN_FULL_SCREEN:
845cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      launch_type = LAUNCH_TYPE_FULLSCREEN;
846cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
847cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case management::LAUNCH_TYPE_OPEN_AS_WINDOW:
848cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      launch_type = LAUNCH_TYPE_WINDOW;
849cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case management::LAUNCH_TYPE_NONE:
851cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      NOTREACHED();
852cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
853cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
854cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetLaunchType(service(), params->id, launch_type);
855cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
856cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
857cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
858cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
85946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ManagementGenerateAppForLinkFunction::ManagementGenerateAppForLinkFunction() {
86046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
86146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
86246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ManagementGenerateAppForLinkFunction::~ManagementGenerateAppForLinkFunction() {
86346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
86446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
86546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ManagementGenerateAppForLinkFunction::FinishCreateBookmarkApp(
8666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const Extension* extension,
86746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const WebApplicationInfo& web_app_info) {
86846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (extension) {
86946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<management::ExtensionInfo> info =
87046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        CreateExtensionInfo(*extension, ExtensionSystem::Get(GetProfile()));
87146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    results_ = management::GenerateAppForLink::Results::Create(*info);
87246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
87346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendResponse(true);
87446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    Release();
87546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  } else {
87646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    error_ = keys::kGenerateAppForLinkInstallError;
87746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendResponse(false);
87846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    Release();
87946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
88046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
88146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
88246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ManagementGenerateAppForLinkFunction::OnFaviconForApp(
88346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const favicon_base::FaviconImageResult& image_result) {
88446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WebApplicationInfo web_app;
88546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  web_app.title = base::UTF8ToUTF16(title_);
88646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  web_app.app_url = launch_url_;
88746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
88846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!image_result.image.IsEmpty()) {
88946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    WebApplicationInfo::IconInfo icon;
89046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    icon.data = image_result.image.AsBitmap();
89146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    icon.width = icon.data.width();
89246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    icon.height = icon.data.height();
89346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    web_app.icons.push_back(icon);
89446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
89546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
89646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bookmark_app_helper_.reset(new BookmarkAppHelper(service(), web_app, NULL));
89746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bookmark_app_helper_->Create(base::Bind(
89846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      &ManagementGenerateAppForLinkFunction::FinishCreateBookmarkApp, this));
89946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
90046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
90146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool ManagementGenerateAppForLinkFunction::RunAsync() {
90246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!user_gesture()) {
90346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    error_ = keys::kGestureNeededForGenerateAppForLinkError;
90446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
90546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
90646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
90746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<management::GenerateAppForLink::Params> params(
90846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      management::GenerateAppForLink::Params::Create(*args_));
90946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
91046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
91146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GURL launch_url(params->url);
91246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!launch_url.is_valid() || !launch_url.SchemeIsHTTPOrHTTPS()) {
91346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidURLError,
91446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                            params->url);
91546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
91646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
91746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
91846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (params->title.empty()) {
91946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    error_ = keys::kEmptyTitleError;
92046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
92146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
92246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
92346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  FaviconService* favicon_service =
92446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FaviconServiceFactory::GetForProfile(GetProfile(),
92546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                           Profile::EXPLICIT_ACCESS);
92646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(favicon_service);
92746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
92846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  title_ = params->title;
92946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  launch_url_ = launch_url;
93046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
931f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  favicon_service->GetFaviconImageForPageURL(
932116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      launch_url,
93346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&ManagementGenerateAppForLinkFunction::OnFaviconForApp, this),
93446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      &cancelable_task_tracker_);
93546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
93646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Matched with a Release() in OnExtensionLoaded().
93746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AddRef();
93846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
93946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Response is sent async in OnExtensionLoaded().
94046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return true;
94146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
94246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)ManagementEventRouter::ManagementEventRouter(content::BrowserContext* context)
9446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    : browser_context_(context), extension_registry_observer_(this) {
9456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ManagementEventRouter::~ManagementEventRouter() {}
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void ManagementEventRouter::OnExtensionLoaded(
9516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    content::BrowserContext* browser_context,
9526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const Extension* extension) {
9536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  BroadcastEvent(extension, management::OnEnabled::kEventName);
9546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
9556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
9566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void ManagementEventRouter::OnExtensionUnloaded(
9576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    content::BrowserContext* browser_context,
9586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const Extension* extension,
9596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    UnloadedExtensionInfo::Reason reason) {
9606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  BroadcastEvent(extension, management::OnDisabled::kEventName);
9616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void ManagementEventRouter::OnExtensionInstalled(
9646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    content::BrowserContext* browser_context,
965116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const Extension* extension,
966116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool is_update) {
9676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  BroadcastEvent(extension, management::OnInstalled::kEventName);
9686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
9693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
9706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void ManagementEventRouter::OnExtensionUninstalled(
9716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    content::BrowserContext* browser_context,
9725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const Extension* extension,
9735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    extensions::UninstallReason reason) {
9746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  BroadcastEvent(extension, management::OnUninstalled::kEventName);
9756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
9766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
9776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void ManagementEventRouter::BroadcastEvent(const Extension* extension,
9786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                           const char* event_name) {
9796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (ui_util::ShouldNotBeVisible(extension, browser_context_))
9806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return;  // Don't dispatch events for built-in extenions.
981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<base::ListValue> args(new base::ListValue());
9823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (event_name == management::OnUninstalled::kEventName) {
9833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    args->Append(new base::StringValue(extension->id()));
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
9856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_ptr<management::ExtensionInfo> info =
9866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        CreateExtensionInfo(*extension, ExtensionSystem::Get(browser_context_));
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    args->Append(info->ToValue().release());
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EventRouter::Get(browser_context_)
9916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      ->BroadcastEvent(scoped_ptr<Event>(new Event(event_name, args.Pass())));
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
994a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ManagementAPI::ManagementAPI(content::BrowserContext* context)
995a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : browser_context_(context) {
9960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EventRouter* event_router = EventRouter::Get(browser_context_);
997a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event_router->RegisterObserver(this, management::OnInstalled::kEventName);
998a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event_router->RegisterObserver(this, management::OnUninstalled::kEventName);
999a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event_router->RegisterObserver(this, management::OnEnabled::kEventName);
1000a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event_router->RegisterObserver(this, management::OnDisabled::kEventName);
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ManagementAPI::~ManagementAPI() {
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ManagementAPI::Shutdown() {
10070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EventRouter::Get(browser_context_)->UnregisterObserver(this);
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1010a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static base::LazyInstance<BrowserContextKeyedAPIFactory<ManagementAPI> >
1011a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    g_factory = LAZY_INSTANCE_INITIALIZER;
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1014a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextKeyedAPIFactory<ManagementAPI>*
1015a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ManagementAPI::GetFactoryInstance() {
10165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return g_factory.Pointer();
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ManagementAPI::OnListenerAdded(const EventListenerInfo& details) {
10206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  management_event_router_.reset(new ManagementEventRouter(browser_context_));
10210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EventRouter::Get(browser_context_)->UnregisterObserver(this);
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace extensions
1025