12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/developer_private/developer_private_api.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "apps/app_load_service.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "apps/saved_files_service.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/base64.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/command_line.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/i18n/file_util_icu.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/lazy_instance.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/devtools/devtools_window.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/developer_private/entry_picker.h"
21b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/extensions/devtools_util.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_disabled_ui.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_error_reporter.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/extension_ui_util.h"
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/extensions/extension_util.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/unpacked_installer.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/updater/extension_updater.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/platform_util.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/chrome_select_file_policy.h"
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/webui/extensions/extension_error_ui_util.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/api/developer_private.h"
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h"
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/url_constants.h"
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/notification_service.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_process_host.h"
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_view_host.h"
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/site_instance.h"
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/storage_partition.h"
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/app_window/app_window.h"
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/app_window/app_window_registry.h"
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_error.h"
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/extension_prefs.h"
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/management_policy.h"
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/notification_types.h"
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "extensions/browser/view_type_utils.h"
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/extension_resource.h"
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h"
613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "extensions/common/install_warning.h"
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/manifest.h"
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/background_info.h"
64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/manifest_handlers/icons_handler.h"
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/incognito_info.h"
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/offline_enabled_info.h"
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/manifest_handlers/options_page_info.h"
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "extensions/common/switches.h"
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/grit/extensions_browser_resources.h"
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_util.h"
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/external_mount_points.h"
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation.h"
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h"
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/isolated_context.h"
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/blob/shareable_file_reference.h"
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/webui/web_ui_util.h"
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::RenderViewHost;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace extensions {
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace developer_private = api::developer_private;
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kUnpackedAppsFolder[] = "apps_target";
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
92116680a4aac90f2aa7413d9095a592090648e557Ben MurdochExtensionService* GetExtensionService(Profile* profile) {
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ExtensionSystem::Get(profile)->extension_service();
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExtensionUpdater* GetExtensionUpdater(Profile* profile) {
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return GetExtensionService(profile)->updater();
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)GURL GetImageURLFromData(const std::string& contents) {
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::string contents_base64;
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Base64Encode(contents, &contents_base64);
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(dvh): make use of content::kDataScheme. Filed as crbug/297301.
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const char kDataURLPrefix[] = "data:;base64,";
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return GURL(kDataURLPrefix + contents_base64);
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)GURL GetDefaultImageURL(developer_private::ItemType type) {
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int icon_resource_id;
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  switch (type) {
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case developer::ITEM_TYPE_LEGACY_PACKAGED_APP:
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case developer::ITEM_TYPE_HOSTED_APP:
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case developer::ITEM_TYPE_PACKAGED_APP:
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      icon_resource_id = IDR_APP_DEFAULT_ICON;
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      break;
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    default:
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      icon_resource_id = IDR_EXTENSION_DEFAULT_ICON;
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      break;
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return GetImageURLFromData(
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          icon_resource_id, ui::SCALE_FACTOR_100P).as_string());
12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// TODO(dvh): This code should be refactored and moved to
12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// extensions::ImageLoader. Also a resize should be performed to avoid
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// potential huge URLs: crbug/297298.
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)GURL ToDataURL(const base::FilePath& path, developer_private::ItemType type) {
13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::string contents;
13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (path.empty() || !base::ReadFileToString(path, &contents))
13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return GetDefaultImageURL(type);
13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return GetImageURLFromData(contents);
13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string GetExtensionID(const RenderViewHost* render_view_host) {
139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!render_view_host->GetSiteInstance())
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return std::string();
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return render_view_host->GetSiteInstance()->GetSiteURL().host();
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void BroadcastItemStateChanged(content::BrowserContext* browser_context,
14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                               developer::EventType event_type,
14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                               const std::string& item_id) {
14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  developer::EventData event_data;
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  event_data.event_type = event_type;
15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  event_data.item_id = item_id;
15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::ListValue> args(new base::ListValue());
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  args->Append(event_data.ToValue().release());
15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<Event> event(new Event(
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      developer_private::OnItemStateChanged::kEventName, args.Pass()));
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EventRouter::Get(browser_context)->BroadcastEvent(event.Pass());
15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace AllowFileAccess = api::developer_private::AllowFileAccess;
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace AllowIncognito = api::developer_private::AllowIncognito;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ChoosePath = api::developer_private::ChoosePath;
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace Enable = api::developer_private::Enable;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace GetItemsInfo = api::developer_private::GetItemsInfo;
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace Inspect = api::developer_private::Inspect;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace PackDirectory = api::developer_private::PackDirectory;
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace Reload = api::developer_private::Reload;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static base::LazyInstance<BrowserContextKeyedAPIFactory<DeveloperPrivateAPI> >
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    g_factory = LAZY_INSTANCE_INITIALIZER;
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextKeyedAPIFactory<DeveloperPrivateAPI>*
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)DeveloperPrivateAPI::GetFactoryInstance() {
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return g_factory.Pointer();
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)DeveloperPrivateAPI* DeveloperPrivateAPI::Get(
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    content::BrowserContext* context) {
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetFactoryInstance()->Get(context);
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)DeveloperPrivateAPI::DeveloperPrivateAPI(content::BrowserContext* context)
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : profile_(Profile::FromBrowserContext(context)) {
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterNotifications();
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochDeveloperPrivateEventRouter::DeveloperPrivateEventRouter(Profile* profile)
19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    : extension_registry_observer_(this), profile_(profile) {
19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  registrar_.Add(this,
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 extensions::NOTIFICATION_EXTENSION_VIEW_REGISTERED,
19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 content::Source<Profile>(profile_));
19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  registrar_.Add(this,
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 extensions::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED,
19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 content::Source<Profile>(profile_));
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // TODO(limasdf): Use scoped_observer instead.
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ErrorConsole::Get(profile)->AddObserver(this);
20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DeveloperPrivateEventRouter::~DeveloperPrivateEventRouter() {
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ErrorConsole::Get(profile_)->RemoveObserver(this);
207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DeveloperPrivateEventRouter::AddExtensionId(
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& extension_id) {
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extension_ids_.insert(extension_id);
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DeveloperPrivateEventRouter::RemoveExtensionId(
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& extension_id) {
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extension_ids_.erase(extension_id);
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DeveloperPrivateEventRouter::Observe(
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int type,
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::NotificationSource& source,
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::NotificationDetails& details) {
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Profile* profile = content::Source<Profile>(source).ptr();
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CHECK(profile);
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CHECK(profile_->IsSameProfile(profile));
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  developer::EventData event_data;
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (type) {
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case extensions::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED: {
230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      event_data.event_type = developer::EVENT_TYPE_VIEW_UNREGISTERED;
231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      event_data.item_id = GetExtensionID(
232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          content::Details<const RenderViewHost>(details).ptr());
233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case extensions::NOTIFICATION_EXTENSION_VIEW_REGISTERED: {
236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      event_data.event_type = developer::EVENT_TYPE_VIEW_REGISTERED;
237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      event_data.item_id = GetExtensionID(
238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          content::Details<const RenderViewHost>(details).ptr());
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
24046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return;
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  BroadcastItemStateChanged(profile, event_data.event_type, event_data.item_id);
24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void DeveloperPrivateEventRouter::OnExtensionLoaded(
25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    content::BrowserContext* browser_context,
25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const Extension* extension) {
25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(profile_->IsSameProfile(Profile::FromBrowserContext(browser_context)));
25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  BroadcastItemStateChanged(
25446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      browser_context, developer::EVENT_TYPE_LOADED, extension->id());
25546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void DeveloperPrivateEventRouter::OnExtensionUnloaded(
25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    content::BrowserContext* browser_context,
25946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const Extension* extension,
26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    UnloadedExtensionInfo::Reason reason) {
26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(profile_->IsSameProfile(Profile::FromBrowserContext(browser_context)));
26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  BroadcastItemStateChanged(
26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      browser_context, developer::EVENT_TYPE_UNLOADED, extension->id());
26446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
26646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void DeveloperPrivateEventRouter::OnExtensionWillBeInstalled(
26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    content::BrowserContext* browser_context,
26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const Extension* extension,
26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    bool is_update,
27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    bool from_ephemeral,
27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& old_name) {
27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(profile_->IsSameProfile(Profile::FromBrowserContext(browser_context)));
27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  BroadcastItemStateChanged(
27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      browser_context, developer::EVENT_TYPE_INSTALLED, extension->id());
27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void DeveloperPrivateEventRouter::OnExtensionUninstalled(
27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    content::BrowserContext* browser_context,
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const Extension* extension,
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    extensions::UninstallReason reason) {
28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(profile_->IsSameProfile(Profile::FromBrowserContext(browser_context)));
28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  BroadcastItemStateChanged(
28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      browser_context, developer::EVENT_TYPE_UNINSTALLED, extension->id());
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DeveloperPrivateEventRouter::OnErrorAdded(const ExtensionError* error) {
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We don't want to handle errors thrown by extensions subscribed to these
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // events (currently only the Apps Developer Tool), because doing so risks
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // entering a loop.
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (extension_ids_.find(error->extension_id()) != extension_ids_.end())
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  BroadcastItemStateChanged(
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      profile_, developer::EVENT_TYPE_ERROR_ADDED, error->extension_id());
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeveloperPrivateAPI::SetLastUnpackedDirectory(const base::FilePath& path) {
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  last_unpacked_directory_ = path;
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeveloperPrivateAPI::RegisterNotifications() {
3020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EventRouter::Get(profile_)->RegisterObserver(
3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      this, developer_private::OnItemStateChanged::kEventName);
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivateAPI::~DeveloperPrivateAPI() {}
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeveloperPrivateAPI::Shutdown() {}
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DeveloperPrivateAPI::OnListenerAdded(
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const EventListenerInfo& details) {
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!developer_private_event_router_) {
313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    developer_private_event_router_.reset(
314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        new DeveloperPrivateEventRouter(profile_));
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  developer_private_event_router_->AddExtensionId(details.extension_id);
318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DeveloperPrivateAPI::OnListenerRemoved(
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const EventListenerInfo& details) {
3220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!EventRouter::Get(profile_)->HasEventListener(
3230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          developer_private::OnItemStateChanged::kEventName)) {
324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    developer_private_event_router_.reset(NULL);
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    developer_private_event_router_->RemoveExtensionId(details.extension_id);
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace api {
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool DeveloperPrivateAutoUpdateFunction::RunSync() {
3331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ExtensionUpdater* updater = GetExtensionUpdater(GetProfile());
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (updater)
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    updater->CheckNow(ExtensionUpdater::CheckParams());
3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SetResult(new base::FundamentalValue(true));
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivateAutoUpdateFunction::~DeveloperPrivateAutoUpdateFunction() {}
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<developer::ItemInfo>
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DeveloperPrivateGetItemsInfoFunction::CreateItemInfo(const Extension& item,
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                     bool item_is_enabled) {
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<developer::ItemInfo> info(new developer::ItemInfo());
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionService* service = system->extension_service();
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionRegistry* registry = ExtensionRegistry::Get(GetProfile());
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info->id = item.id();
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info->name = item.name();
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info->enabled = service->IsExtensionEnabled(info->id);
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  info->offline_enabled = OfflineEnabledInfo::IsOfflineEnabled(&item);
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info->version = item.VersionString();
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info->description = item.description();
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (item.is_app()) {
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (item.is_legacy_packaged_app())
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info->type = developer::ITEM_TYPE_LEGACY_PACKAGED_APP;
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else if (item.is_hosted_app())
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info->type = developer::ITEM_TYPE_HOSTED_APP;
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else if (item.is_platform_app())
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info->type = developer::ITEM_TYPE_PACKAGED_APP;
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (item.is_theme()) {
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info->type = developer::ITEM_TYPE_THEME;
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (item.is_extension()) {
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info->type = developer::ITEM_TYPE_EXTENSION;
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (Manifest::IsUnpackedLocation(item.location())) {
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info->path.reset(
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new std::string(base::UTF16ToUTF8(item.path().LossyDisplayName())));
378c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // If the ErrorConsole is enabled and the extension is unpacked, use the
379c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // more detailed errors from the ErrorConsole. Otherwise, use the install
380c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // warnings (using both is redundant).
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ErrorConsole* error_console = ErrorConsole::Get(GetProfile());
382c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (error_console->IsEnabledForAppsDeveloperTools() &&
383c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        item.location() == Manifest::UNPACKED) {
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const ErrorList& errors = error_console->GetErrorsForExtension(item.id());
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!errors.empty()) {
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        for (ErrorList::const_iterator iter = errors.begin();
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             iter != errors.end();
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             ++iter) {
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          switch ((*iter)->type()) {
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            case ExtensionError::MANIFEST_ERROR:
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              info->manifest_errors.push_back(
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  make_linked_ptr((*iter)->ToValue().release()));
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              break;
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            case ExtensionError::RUNTIME_ERROR: {
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              const RuntimeError* error =
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  static_cast<const RuntimeError*>(*iter);
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              scoped_ptr<base::DictionaryValue> value = error->ToValue();
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              bool can_inspect = content::RenderViewHost::FromID(
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     error->render_process_id(),
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     error->render_view_id()) != NULL;
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              value->SetBoolean("canInspect", can_inspect);
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              info->runtime_errors.push_back(make_linked_ptr(value.release()));
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              break;
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            }
4050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            case ExtensionError::NUM_ERROR_TYPES:
4060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              NOTREACHED();
4070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              break;
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          }
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      for (std::vector<InstallWarning>::const_iterator it =
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               item.install_warnings().begin();
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           it != item.install_warnings().end();
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           ++it) {
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        scoped_ptr<developer::InstallWarning> warning(
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            new developer::InstallWarning);
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        warning->message = it->message;
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        info->install_warnings.push_back(make_linked_ptr(warning.release()));
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
4213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  info->incognito_enabled = util::IsIncognitoEnabled(item.id(), GetProfile());
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info->wants_file_access = item.wants_file_access();
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  info->allow_file_access = util::AllowFileAccess(item.id(), GetProfile());
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  info->allow_reload = Manifest::IsUnpackedLocation(item.location());
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  info->is_unpacked = Manifest::IsUnpackedLocation(item.location());
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  info->terminated = registry->terminated_extensions().Contains(item.id());
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info->allow_incognito = item.can_be_incognito_enabled();
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info->homepage_url.reset(new std::string(
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ManifestURL::GetHomepageURL(&item).spec()));
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!OptionsPageInfo::GetOptionsPage(&item).is_empty()) {
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info->options_url.reset(
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new std::string(OptionsPageInfo::GetOptionsPage(&item).spec()));
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ManifestURL::GetUpdateURL(&item).is_empty()) {
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info->update_url.reset(
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new std::string(ManifestURL::GetUpdateURL(&item).spec()));
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (item.is_app()) {
445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    info->app_launch_url.reset(
446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        new std::string(AppLaunchInfo::GetFullLaunchURL(&item).spec()));
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info->may_disable = system->management_policy()->
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UserMayModifySettings(&item, NULL);
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info->is_app = item.is_app();
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info->views = GetInspectablePagesForExtension(&item, item_is_enabled);
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return info.Pass();
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
45768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DeveloperPrivateGetItemsInfoFunction::GetIconsOnFileThread(
45868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ItemInfoList item_list,
45968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::map<std::string, ExtensionResource> idToIcon) {
46068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (ItemInfoList::iterator iter = item_list.begin();
46168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)       iter != item_list.end(); ++iter) {
46268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    developer_private::ItemInfo* info = iter->get();
46368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    std::map<std::string, ExtensionResource>::const_iterator resource_ptr
46468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        = idToIcon.find(info->id);
46568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (resource_ptr != idToIcon.end()) {
46668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      info->icon_url =
46768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          ToDataURL(resource_ptr->second.GetFilePath(), info->type).spec();
46868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
46968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
47068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
47168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  results_ = developer::GetItemsInfo::Results::Create(item_list);
47268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
47368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::Bind(&DeveloperPrivateGetItemsInfoFunction::SendResponse,
47468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 this,
47568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 true));
47668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
47768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeveloperPrivateGetItemsInfoFunction::
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetInspectablePagesForExtensionProcess(
480424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        const Extension* extension,
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const std::set<content::RenderViewHost*>& views,
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ItemInspectViewList* result) {
483424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool has_generated_background_page =
484424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      BackgroundInfo::HasGeneratedBackgroundPage(extension);
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::set<content::RenderViewHost*>::const_iterator iter = views.begin();
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != views.end(); ++iter) {
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::RenderViewHost* host = *iter;
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::WebContents* web_contents =
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::WebContents::FromRenderViewHost(host);
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ViewType host_type = GetViewType(web_contents);
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (VIEW_TYPE_EXTENSION_POPUP == host_type ||
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        VIEW_TYPE_EXTENSION_DIALOG == host_type)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::RenderProcessHost* process = host->GetProcess();
496424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    bool is_background_page =
497424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        (web_contents->GetURL() == BackgroundInfo::GetBackgroundURL(extension));
498424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    result->push_back(constructInspectView(
499424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        web_contents->GetURL(),
500424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        process->GetID(),
501424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        host->GetRoutingID(),
502424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        process->GetBrowserContext()->IsOffTheRecord(),
503424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        is_background_page && has_generated_background_page));
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DeveloperPrivateGetItemsInfoFunction::GetAppWindowPagesForExtensionProfile(
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Extension* extension,
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ItemInspectViewList* result) {
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppWindowRegistry* registry = AppWindowRegistry::Get(GetProfile());
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!registry) return;
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const AppWindowRegistry::AppWindowList windows =
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      registry->GetAppWindowsForApp(extension->id());
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
516424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool has_generated_background_page =
517424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      BackgroundInfo::HasGeneratedBackgroundPage(extension);
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (AppWindowRegistry::const_iterator it = windows.begin();
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != windows.end();
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::WebContents* web_contents = (*it)->web_contents();
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RenderViewHost* host = web_contents->GetRenderViewHost();
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::RenderProcessHost* process = host->GetProcess();
524424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    bool is_background_page =
525424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        (web_contents->GetURL() == BackgroundInfo::GetBackgroundURL(extension));
526424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    result->push_back(constructInspectView(
527424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        web_contents->GetURL(),
528424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        process->GetID(),
529424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        host->GetRoutingID(),
530424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        process->GetBrowserContext()->IsOffTheRecord(),
531424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        is_background_page && has_generated_background_page));
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)linked_ptr<developer::ItemInspectView> DeveloperPrivateGetItemsInfoFunction::
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    constructInspectView(
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const GURL& url,
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        int render_process_id,
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        int render_view_id,
5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        bool incognito,
5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        bool generated_background_page) {
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  linked_ptr<developer::ItemInspectView> view(new developer::ItemInspectView());
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (url.scheme() == kExtensionScheme) {
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No leading slash.
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    view->path = url.path().substr(1);
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // For live pages, use the full URL.
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    view->path = url.spec();
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view->render_process_id = render_process_id;
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view->render_view_id = render_view_id;
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view->incognito = incognito;
5553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  view->generated_background_page = generated_background_page;
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return view;
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ItemInspectViewList DeveloperPrivateGetItemsInfoFunction::
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetInspectablePagesForExtension(
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        const Extension* extension,
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        bool extension_is_enabled) {
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ItemInspectViewList result;
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Get the extension process's active views.
565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ProcessManager* process_manager =
5661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ExtensionSystem::Get(GetProfile())->process_manager();
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetInspectablePagesForExtensionProcess(
568424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      extension,
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      process_manager->GetRenderViewHostsForExtension(extension->id()),
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &result);
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Get app window views.
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetAppWindowPagesForExtensionProfile(extension, &result);
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Include a link to start the lazy background page, if applicable.
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (BackgroundInfo::HasLazyBackgroundPage(extension) &&
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_is_enabled &&
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !process_manager->GetBackgroundHostForExtension(extension->id())) {
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result.push_back(constructInspectView(
5803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        BackgroundInfo::GetBackgroundURL(extension),
5813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        -1,
5823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        -1,
5833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        false,
5843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        BackgroundInfo::HasGeneratedBackgroundPage(extension)));
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
587116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ExtensionService* service = GetExtensionService(GetProfile());
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Repeat for the incognito process, if applicable. Don't try to get
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // app windows for incognito process.
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (service->profile()->HasOffTheRecordProfile() &&
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IncognitoInfo::IsSplitMode(extension)) {
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    process_manager = ExtensionSystem::Get(
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        service->profile()->GetOffTheRecordProfile())->process_manager();
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetInspectablePagesForExtensionProcess(
595424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        extension,
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        process_manager->GetRenderViewHostsForExtension(extension->id()),
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &result);
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (BackgroundInfo::HasLazyBackgroundPage(extension) &&
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        extension_is_enabled &&
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !process_manager->GetBackgroundHostForExtension(extension->id())) {
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result.push_back(constructInspectView(
6033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        BackgroundInfo::GetBackgroundURL(extension),
6043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        -1,
6053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        -1,
6063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        false,
6073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        BackgroundInfo::HasGeneratedBackgroundPage(extension)));
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
614010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeveloperPrivateGetItemsInfoFunction::RunAsync() {
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<developer::GetItemsInfo::Params> params(
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      developer::GetItemsInfo::Params::Create(*args_));
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool include_disabled = params->include_disabled;
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool include_terminated = params->include_terminated;
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ExtensionSet items;
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionRegistry* registry = ExtensionRegistry::Get(GetProfile());
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  items.InsertAll(registry->enabled_extensions());
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (include_disabled) {
6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    items.InsertAll(registry->disabled_extensions());
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (include_terminated) {
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    items.InsertAll(registry->terminated_extensions());
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionService* service =
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ExtensionSystem::Get(GetProfile())->extension_service();
63868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::map<std::string, ExtensionResource> id_to_icon;
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ItemInfoList item_list;
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (ExtensionSet::const_iterator iter = items.begin(); iter != items.end();
642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       ++iter) {
6437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const Extension& item = *iter->get();
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
64568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ExtensionResource item_resource =
64668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        IconsInfo::GetIconResource(&item,
64768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                   extension_misc::EXTENSION_ICON_MEDIUM,
64868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                   ExtensionIconSet::MATCH_BIGGER);
64968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    id_to_icon[item.id()] = item_resource;
65068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Don't show component extensions and invisible apps.
652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (ui_util::ShouldNotBeVisible(&item, GetProfile()))
65390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      continue;
65490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    item_list.push_back(make_linked_ptr<developer::ItemInfo>(
65690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        CreateItemInfo(
65790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            item, service->IsExtensionEnabled(item.id())).release()));
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
66068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
66168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::Bind(&DeveloperPrivateGetItemsInfoFunction::GetIconsOnFileThread,
66268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 this,
66368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 item_list,
66468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 id_to_icon));
665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivateGetItemsInfoFunction::~DeveloperPrivateGetItemsInfoFunction() {}
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool DeveloperPrivateAllowFileAccessFunction::RunSync() {
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AllowFileAccess::Params> params(
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AllowFileAccess::Params::Create(*args_));
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(user_gesture_);
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ManagementPolicy* management_policy = system->management_policy();
680cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const Extension* extension =
681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ExtensionRegistry::Get(GetProfile())
682cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ->GetExtensionById(params->item_id, ExtensionRegistry::EVERYTHING);
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool result = true;
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!extension) {
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result = false;
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (!management_policy->UserMayModifySettings(extension, NULL)) {
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Attempt to change allow file access of an extension that "
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               << "non-usermanagable was made. Extension id : "
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               << extension->id();
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result = false;
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
6935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    util::SetAllowFileAccess(extension->id(), GetProfile(), params->allow);
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result = true;
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivateAllowFileAccessFunction::
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ~DeveloperPrivateAllowFileAccessFunction() {}
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool DeveloperPrivateAllowIncognitoFunction::RunSync() {
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AllowIncognito::Params> params(
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AllowIncognito::Params::Create(*args_));
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
708cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const Extension* extension =
709cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ExtensionRegistry::Get(GetProfile())
710cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ->GetExtensionById(params->item_id, ExtensionRegistry::EVERYTHING);
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool result = true;
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!extension)
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result = false;
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    util::SetIsIncognitoEnabled(extension->id(), GetProfile(), params->allow);
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivateAllowIncognitoFunction::
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ~DeveloperPrivateAllowIncognitoFunction() {}
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool DeveloperPrivateReloadFunction::RunSync() {
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Reload::Params> params(Reload::Params::Create(*args_));
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!params->item_id.empty());
729116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ExtensionService* service = GetExtensionService(GetProfile());
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service->ReloadExtension(params->item_id);
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool DeveloperPrivateShowPermissionsDialogFunction::RunSync() {
735868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id_));
736868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK(!extension_id_.empty());
7375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppWindowRegistry* registry = AppWindowRegistry::Get(GetProfile());
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(registry);
7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppWindow* app_window =
7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      registry->GetAppWindowForRenderViewHost(render_view_host());
7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  prompt_.reset(new ExtensionInstallPrompt(app_window->web_contents()));
742cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const Extension* extension =
743cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ExtensionRegistry::Get(GetProfile())
744cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING);
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!extension)
747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Released by InstallUIAbort or InstallUIProceed.
750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddRef();
751868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::vector<base::FilePath> retained_file_paths;
75246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (extension->permissions_data()->HasAPIPermission(
75346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          APIPermission::kFileSystem)) {
754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    std::vector<apps::SavedFileEntry> retained_file_entries =
7551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        apps::SavedFilesService::Get(GetProfile())
7561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            ->GetAllFileEntries(extension_id_);
757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (size_t i = 0; i < retained_file_entries.size(); i++) {
758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      retained_file_paths.push_back(retained_file_entries[i].path);
759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
761868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  prompt_->ReviewPermissions(this, extension, retained_file_paths);
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivateReloadFunction::~DeveloperPrivateReloadFunction() {}
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
767868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This is called when the user clicks "Revoke File Access."
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DeveloperPrivateShowPermissionsDialogFunction::InstallUIProceed() {
769116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Profile* profile = GetProfile();
770116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const Extension* extension = ExtensionRegistry::Get(
771116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      profile)->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING);
772116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  apps::SavedFilesService::Get(profile)->ClearQueue(extension);
7735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  apps::AppLoadService::Get(profile)
7745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ->RestartApplicationIfRunning(extension_id_);
775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SendResponse(true);
776868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Release();
777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DeveloperPrivateShowPermissionsDialogFunction::InstallUIAbort(
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool user_initiated) {
781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SendResponse(true);
782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Release();
783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DeveloperPrivateShowPermissionsDialogFunction::
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DeveloperPrivateShowPermissionsDialogFunction() {}
787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DeveloperPrivateShowPermissionsDialogFunction::
789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ~DeveloperPrivateShowPermissionsDialogFunction() {}
790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivateEnableFunction::DeveloperPrivateEnableFunction() {}
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool DeveloperPrivateEnableFunction::RunSync() {
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Enable::Params> params(Enable::Params::Create(*args_));
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string extension_id = params->item_id;
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
799cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const Extension* extension =
800116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ExtensionRegistry::Get(GetProfile())->GetExtensionById(
801116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          extension_id, ExtensionRegistry::EVERYTHING);
802f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!extension) {
803f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    LOG(ERROR) << "Did not find extension with id " << extension_id;
804f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
806cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
807cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ManagementPolicy* policy = system->management_policy();
808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool enable = params->enable;
809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!policy->UserMayModifySettings(extension, NULL) ||
810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      (!enable && policy->MustRemainEnabled(extension, NULL)) ||
811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      (enable && policy->MustRemainDisabled(extension, NULL, NULL))) {
812f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    LOG(ERROR) << "Attempt to change enable state denied by management policy. "
813f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               << "Extension id: " << extension_id.c_str();
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ExtensionService* service = system->extension_service();
818f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (enable) {
819a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ExtensionPrefs* prefs = ExtensionPrefs::Get(GetProfile());
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (prefs->DidExtensionEscalatePermissions(extension_id)) {
8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      AppWindowRegistry* registry = AppWindowRegistry::Get(GetProfile());
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CHECK(registry);
8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      AppWindow* app_window =
8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          registry->GetAppWindowForRenderViewHost(render_view_host());
8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!app_window) {
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ShowExtensionDisabledDialog(
8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          service, app_window->web_contents(), extension);
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if ((prefs->GetDisableReasons(extension_id) &
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  Extension::DISABLE_UNSUPPORTED_REQUIREMENT) &&
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               !requirements_checker_.get()) {
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Recheck the requirements.
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_refptr<const Extension> extension =
836c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          service->GetExtensionById(extension_id, true);
837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      requirements_checker_.reset(new RequirementsChecker);
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Released by OnRequirementsChecked.
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddRef();
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      requirements_checker_->Check(
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          extension,
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(&DeveloperPrivateEnableFunction::OnRequirementsChecked,
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     this, extension_id));
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      service->EnableExtension(extension_id);
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Make sure any browser action contained within it is not hidden.
848b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      ExtensionActionAPI::SetBrowserActionVisibility(
849b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          prefs, extension->id(), true);
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    service->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeveloperPrivateEnableFunction::OnRequirementsChecked(
858010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& extension_id,
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<std::string> requirements_errors) {
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (requirements_errors.empty()) {
861116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GetExtensionService(GetProfile())->EnableExtension(extension_id);
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ExtensionErrorReporter::GetInstance()->ReportError(
8645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::UTF8ToUTF16(JoinString(requirements_errors, ' ')),
8655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        true);  // Be noisy.
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Release();
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivateEnableFunction::~DeveloperPrivateEnableFunction() {}
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool DeveloperPrivateInspectFunction::RunSync() {
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<developer::Inspect::Params> params(
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      developer::Inspect::Params::Create(*args_));
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const developer::InspectOptions& options = params->options;
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int render_process_id;
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringToInt(options.render_process_id, &render_process_id);
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (render_process_id == -1) {
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This is a lazy background page. Identify if it is a normal
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // or incognito background page.
884116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const Extension* extension = ExtensionRegistry::Get(
885116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        GetProfile())->enabled_extensions().GetByID(options.extension_id);
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(extension);
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Wakes up the background page and  opens the inspect window.
8881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    devtools_util::InspectBackgroundPage(extension, GetProfile());
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int render_view_id;
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringToInt(options.render_view_id, &render_view_id);
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::RenderViewHost* host = content::RenderViewHost::FromID(
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      render_process_id, render_view_id);
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!host || !content::WebContents::FromRenderViewHost(host)) {
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This can happen if the host has gone away since the page was displayed.
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DevToolsWindow::OpenDevToolsWindow(
9036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      content::WebContents::FromRenderViewHost(host));
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivateInspectFunction::~DeveloperPrivateInspectFunction() {}
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
909010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeveloperPrivateLoadUnpackedFunction::RunAsync() {
910a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 select_title =
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY);
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Balanced in FileSelected / FileSelectionCanceled.
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddRef();
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool result = ShowPicker(
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::SelectFileDialog::SELECT_FOLDER,
9171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      DeveloperPrivateAPI::Get(GetProfile())->GetLastUnpackedDirectory(),
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      select_title,
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::SelectFileDialog::FileTypeInfo(),
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0);
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeveloperPrivateLoadUnpackedFunction::FileSelected(
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path) {
926116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ExtensionService* service = GetExtensionService(GetProfile());
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UnpackedInstaller::Create(service)->Load(path);
9281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DeveloperPrivateAPI::Get(GetProfile())->SetLastUnpackedDirectory(path);
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendResponse(true);
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Release();
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeveloperPrivateLoadUnpackedFunction::FileSelectionCanceled() {
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendResponse(false);
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Release();
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DeveloperPrivateChooseEntryFunction::ShowPicker(
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::SelectFileDialog::Type picker_type,
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& last_directory,
941a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& select_title,
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ui::SelectFileDialog::FileTypeInfo& info,
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int file_type_index) {
9445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppWindowRegistry* registry = AppWindowRegistry::Get(GetProfile());
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(registry);
9465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppWindow* app_window =
9475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      registry->GetAppWindowForRenderViewHost(render_view_host());
9485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!app_window) {
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The entry picker will hold a reference to this function instance,
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and subsequent sending of the function response) until the user has
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // selected a file or cancelled the picker. At that point, the picker will
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // delete itself.
9565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  new EntryPicker(this,
9575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  app_window->web_contents(),
9585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  picker_type,
9595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  last_directory,
9605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  select_title,
9615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  info,
9625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  file_type_index);
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
966010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeveloperPrivateChooseEntryFunction::RunAsync() {
967010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return false;
968010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivateChooseEntryFunction::~DeveloperPrivateChooseEntryFunction() {}
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeveloperPrivatePackDirectoryFunction::OnPackSuccess(
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& crx_file,
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& pem_file) {
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  developer::PackDirectoryResponse response;
9765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  response.message = base::UTF16ToUTF8(
9775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      PackExtensionJob::StandardSuccessMessage(crx_file, pem_file));
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response.status = developer::PACK_STATUS_SUCCESS;
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  results_ = developer::PackDirectory::Results::Create(response);
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendResponse(true);
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Release();
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeveloperPrivatePackDirectoryFunction::OnPackFailure(
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& error,
986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ExtensionCreator::ErrorType error_type) {
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  developer::PackDirectoryResponse response;
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response.message = error;
989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (error_type == ExtensionCreator::kCRXExists) {
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response.item_path = item_path_str_;
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response.pem_path = key_path_str_;
992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response.override_flags = ExtensionCreator::kOverwriteCRX;
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response.status = developer::PACK_STATUS_WARNING;
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response.status = developer::PACK_STATUS_ERROR;
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  results_ = developer::PackDirectory::Results::Create(response);
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendResponse(true);
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Release();
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeveloperPrivatePackDirectoryFunction::RunAsync() {
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<PackDirectory::Params> params(
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PackDirectory::Params::Create(*args_));
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int flags = params->flags;
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  item_path_str_ = params->path;
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  key_path_str_ = params->private_key_path;
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath root_directory =
101258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::FilePath::FromUTF8Unsafe(item_path_str_);
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
101458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::FilePath key_file = base::FilePath::FromUTF8Unsafe(key_path_str_);
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  developer::PackDirectoryResponse response;
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (root_directory.empty()) {
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (item_path_str_.empty())
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      response.message = l10n_util::GetStringUTF8(
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_REQUIRED);
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      response.message = l10n_util::GetStringUTF8(
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID);
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response.status = developer::PACK_STATUS_ERROR;
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    results_ = developer::PackDirectory::Results::Create(response);
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SendResponse(true);
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!key_path_str_.empty() && key_file.empty()) {
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response.message = l10n_util::GetStringUTF8(
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID);
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response.status = developer::PACK_STATUS_ERROR;
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    results_ = developer::PackDirectory::Results::Create(response);
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SendResponse(true);
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Balanced in OnPackSuccess / OnPackFailure.
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddRef();
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1043c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pack_job_ = new PackExtensionJob(this, root_directory, key_file, flags);
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pack_job_->Start();
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivatePackDirectoryFunction::DeveloperPrivatePackDirectoryFunction()
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){}
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivatePackDirectoryFunction::~DeveloperPrivatePackDirectoryFunction()
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){}
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivateLoadUnpackedFunction::~DeveloperPrivateLoadUnpackedFunction() {}
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1056010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeveloperPrivateLoadDirectoryFunction::RunAsync() {
1057c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(grv) : add unittests.
10585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string directory_url_str;
10595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string filesystem_name;
10605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string filesystem_path;
10615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &filesystem_name));
10635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &filesystem_path));
10645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &directory_url_str));
10655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1066116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  context_ = content::BrowserContext::GetStoragePartition(
1067116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      GetProfile(), render_view_host()->GetSiteInstance())
1068116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 ->GetFileSystemContext();
1069116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
10705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Directory url is non empty only for syncfilesystem.
10715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (directory_url_str != "") {
107203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemURL directory_url =
10735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        context_->CrackURL(GURL(directory_url_str));
1074116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!directory_url.is_valid() ||
107503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        directory_url.type() != storage::kFileSystemTypeSyncable) {
10765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SetError("DirectoryEntry of unsupported filesystem.");
10775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
10785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1079116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return LoadByFileSystemAPI(directory_url);
10805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1081c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Check if the DirecotryEntry is the instance of chrome filesystem.
10825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!app_file_handler_util::ValidateFileEntryAndGetPath(filesystem_name,
10835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                            filesystem_path,
10845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                            render_view_host_,
10855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                            &project_base_path_,
1086116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                            &error_)) {
1087116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      SetError("DirectoryEntry of unsupported filesystem.");
1088116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return false;
1089116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
1090116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1091116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Try to load using the FileSystem API backend, in case the filesystem
1092116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // points to a non-native local directory.
1093116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string filesystem_id;
1094116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool cracked =
109503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        storage::CrackIsolatedFileSystemName(filesystem_name, &filesystem_id);
1096116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CHECK(cracked);
1097116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::FilePath virtual_path =
109803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        storage::IsolatedContext::GetInstance()
1099116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            ->CreateVirtualRootPath(filesystem_id)
1100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            .Append(base::FilePath::FromUTF8Unsafe(filesystem_path));
110103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemURL directory_url = context_->CreateCrackedFileSystemURL(
1102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        extensions::Extension::GetBaseURLFromExtensionId(extension_id()),
110303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        storage::kFileSystemTypeIsolated,
1104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        virtual_path);
1105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (directory_url.is_valid() &&
110703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        directory_url.type() != storage::kFileSystemTypeNativeLocal &&
110803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        directory_url.type() != storage::kFileSystemTypeRestrictedNativeLocal &&
110903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        directory_url.type() != storage::kFileSystemTypeDragged) {
1110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return LoadByFileSystemAPI(directory_url);
1111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
11125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Load();
1114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
11175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1119116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool DeveloperPrivateLoadDirectoryFunction::LoadByFileSystemAPI(
112003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& directory_url) {
1121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string directory_url_str = directory_url.ToGURL().spec();
1122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  size_t pos = 0;
1124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Parse the project directory name from the project url. The project url is
1125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // expected to have project name as the suffix.
1126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if ((pos = directory_url_str.rfind("/")) == std::string::npos) {
1127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SetError("Invalid Directory entry.");
1128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
1129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string project_name;
1132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  project_name = directory_url_str.substr(pos + 1);
1133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  project_base_url_ = directory_url_str.substr(0, pos + 1);
1134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::FilePath project_path(GetProfile()->GetPath());
1136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  project_path = project_path.AppendASCII(kUnpackedAppsFolder);
1137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  project_path = project_path.Append(
1138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::FilePath::FromUTF8Unsafe(project_name));
1139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  project_base_path_ = project_path;
1141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
1143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&DeveloperPrivateLoadDirectoryFunction::
1144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     ClearExistingDirectoryContent,
1145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 this,
1146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 project_base_path_));
1147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return true;
1148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
11505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DeveloperPrivateLoadDirectoryFunction::Load() {
1151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ExtensionService* service = GetExtensionService(GetProfile());
11525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UnpackedInstaller::Create(service)->Load(project_base_path_);
1153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(grv) : The unpacked installer should fire an event when complete
11555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // and return the extension_id.
11565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetResult(new base::StringValue("-1"));
11575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SendResponse(true);
1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DeveloperPrivateLoadDirectoryFunction::ClearExistingDirectoryContent(
11615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::FilePath& project_path) {
1162a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
1163a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Clear the project directory before copying new files.
1164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::DeleteFile(project_path, true /*recursive*/);
1165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pending_copy_operations_count_ = 1;
1167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
11695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&DeveloperPrivateLoadDirectoryFunction::
1170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 ReadDirectoryByFileSystemAPI,
1171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 this, project_path, project_path.BaseName()));
1172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1174116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid DeveloperPrivateLoadDirectoryFunction::ReadDirectoryByFileSystemAPI(
11755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::FilePath& project_path,
11765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::FilePath& destination_path) {
1177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GURL project_url = GURL(project_base_url_ + destination_path.AsUTF8Unsafe());
117803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemURL url = context_->CrackURL(project_url);
1179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  context_->operation_runner()->ReadDirectory(
11815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      url, base::Bind(&DeveloperPrivateLoadDirectoryFunction::
1182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      ReadDirectoryByFileSystemAPICb,
1183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                      this, project_path, destination_path));
1184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1186116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid DeveloperPrivateLoadDirectoryFunction::ReadDirectoryByFileSystemAPICb(
1187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::FilePath& project_path,
1188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::FilePath& destination_path,
11895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error status,
119003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemOperation::FileEntryList& file_list,
1191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool has_more) {
11925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (status != base::File::FILE_OK) {
1193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DLOG(ERROR) << "Error in copying files from sync filesystem.";
1194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We add 1 to the pending copy operations for both files and directories. We
1198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // release the directory copy operation once all the files under the directory
1199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // are added for copying. We do that to ensure that pendingCopyOperationsCount
1200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // does not become zero before all copy operations are finished.
1201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // In case the directory happens to be executing the last copy operation it
1202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // will call SendResponse to send the response to the API. The pending copy
1203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // operations of files are released by the CopyFile function.
12045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pending_copy_operations_count_ += file_list.size();
1205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < file_list.size(); ++i) {
1207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (file_list[i].is_directory) {
1208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ReadDirectoryByFileSystemAPI(project_path.Append(file_list[i].name),
1209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   destination_path.Append(file_list[i].name));
1210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      continue;
1211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
1212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GURL project_url = GURL(project_base_url_ +
1214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        destination_path.Append(file_list[i].name).AsUTF8Unsafe());
121503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemURL url = context_->CrackURL(project_url);
1216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::FilePath target_path = project_path;
1218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    target_path = target_path.Append(file_list[i].name);
1219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    context_->operation_runner()->CreateSnapshotFile(
1221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        url,
12225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&DeveloperPrivateLoadDirectoryFunction::SnapshotFileCallback,
1223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            this,
1224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            target_path));
1225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!has_more) {
1228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Directory copy operation released here.
1229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    pending_copy_operations_count_--;
1230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!pending_copy_operations_count_) {
1232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      content::BrowserThread::PostTask(
1233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          content::BrowserThread::UI, FROM_HERE,
1234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          base::Bind(&DeveloperPrivateLoadDirectoryFunction::SendResponse,
1235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     this,
1236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     success_));
1237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
1238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DeveloperPrivateLoadDirectoryFunction::SnapshotFileCallback(
1242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::FilePath& target_path,
12435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error result,
12445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::File::Info& file_info,
1245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::FilePath& src_path,
124603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const scoped_refptr<storage::ShareableFileReference>& file_ref) {
12475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result != base::File::FILE_OK) {
1248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetError("Error in copying files from sync filesystem.");
1249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    success_ = false;
1250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
12545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&DeveloperPrivateLoadDirectoryFunction::CopyFile,
1255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 this,
1256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 src_path,
1257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 target_path));
1258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DeveloperPrivateLoadDirectoryFunction::CopyFile(
1261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::FilePath& src_path,
1262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::FilePath& target_path) {
1263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!base::CreateDirectory(target_path.DirName())) {
1264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetError("Error in copying files from sync filesystem.");
1265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    success_ = false;
1266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (success_)
12697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::CopyFile(src_path, target_path);
1270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(pending_copy_operations_count_ > 0);
12725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pending_copy_operations_count_--;
1273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!pending_copy_operations_count_) {
1275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
12765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&DeveloperPrivateLoadDirectoryFunction::Load,
12775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   this));
1278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DeveloperPrivateLoadDirectoryFunction::DeveloperPrivateLoadDirectoryFunction()
12825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : pending_copy_operations_count_(0), success_(true) {}
1283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DeveloperPrivateLoadDirectoryFunction::~DeveloperPrivateLoadDirectoryFunction()
12855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {}
1286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeveloperPrivateChoosePathFunction::RunAsync() {
12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<developer::ChoosePath::Params> params(
12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      developer::ChoosePath::Params::Create(*args_));
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::SelectFileDialog::Type type = ui::SelectFileDialog::SELECT_FOLDER;
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::SelectFileDialog::FileTypeInfo info;
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (params->select_type == developer::SELECT_TYPE_FILE) {
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    type = ui::SelectFileDialog::SELECT_OPEN_FILE;
12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 select_title;
12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int file_type_index = 0;
1300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (params->file_type == developer::FILE_TYPE_LOAD) {
13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    select_title = l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY);
1302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  } else if (params->file_type == developer::FILE_TYPE_PEM) {
13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    select_title = l10n_util::GetStringUTF16(
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDS_EXTENSION_PACK_DIALOG_SELECT_KEY);
13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info.extensions.push_back(std::vector<base::FilePath::StringType>());
13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info.extensions.front().push_back(FILE_PATH_LITERAL("pem"));
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info.extension_description_overrides.push_back(
13082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        l10n_util::GetStringUTF16(
13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION));
13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info.include_all_files = true;
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_type_index = 1;
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Balanced by FileSelected / FileSelectionCanceled.
13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddRef();
13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool result = ShowPicker(
13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type,
13201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      DeveloperPrivateAPI::Get(GetProfile())->GetLastUnpackedDirectory(),
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      select_title,
13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info,
13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      file_type_index);
13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeveloperPrivateChoosePathFunction::FileSelected(
13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path) {
13295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetResult(new base::StringValue(base::UTF16ToUTF8(path.LossyDisplayName())));
13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendResponse(true);
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Release();
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeveloperPrivateChoosePathFunction::FileSelectionCanceled() {
13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendResponse(false);
13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Release();
13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeveloperPrivateChoosePathFunction::~DeveloperPrivateChoosePathFunction() {}
13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool DeveloperPrivateIsProfileManagedFunction::RunSync() {
1342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SetResult(new base::FundamentalValue(GetProfile()->IsSupervised()));
1343424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return true;
1344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)DeveloperPrivateIsProfileManagedFunction::
1347424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ~DeveloperPrivateIsProfileManagedFunction() {
1348424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1349424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
13505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DeveloperPrivateRequestFileSourceFunction::
13515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DeveloperPrivateRequestFileSourceFunction() {}
13525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DeveloperPrivateRequestFileSourceFunction::
13545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ~DeveloperPrivateRequestFileSourceFunction() {}
13555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1356010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeveloperPrivateRequestFileSourceFunction::RunAsync() {
13575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<developer::RequestFileSource::Params> params(
13585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      developer::RequestFileSource::Params::Create(*args_));
13595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
13605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* dict = NULL;
13625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!params->dict->GetAsDictionary(&dict)) {
13635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED();
13645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
13655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
13665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddRef();  // Balanced in LaunchCallback().
13685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  error_ui_util::HandleRequestFileSource(
13695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dict,
13705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetProfile(),
13715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&DeveloperPrivateRequestFileSourceFunction::LaunchCallback,
13725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this)));
13735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
13745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
13755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DeveloperPrivateRequestFileSourceFunction::LaunchCallback(
13775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::DictionaryValue& results) {
13785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetResult(results.DeepCopy());
13795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SendResponse(true);
1380010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Release();  // Balanced in RunAsync().
13815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
13825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DeveloperPrivateOpenDevToolsFunction::DeveloperPrivateOpenDevToolsFunction() {}
13845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DeveloperPrivateOpenDevToolsFunction::~DeveloperPrivateOpenDevToolsFunction() {}
13855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1386010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DeveloperPrivateOpenDevToolsFunction::RunAsync() {
13875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<developer::OpenDevTools::Params> params(
13885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      developer::OpenDevTools::Params::Create(*args_));
13895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
13905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* dict = NULL;
13925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!params->dict->GetAsDictionary(&dict)) {
13935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED();
13945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
13955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
13965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  error_ui_util::HandleOpenDevTools(dict);
13985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
14005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
14015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1402c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace api
14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1404c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace extensions
1405