12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/unpacked_installer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
11a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_install_prompt.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_install_ui.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_prefs.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/permissions_updater.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/api/plugins/plugins_handler.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_file_util.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/manifest.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/id_util.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/string_ordinal.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUnpackedExtensionsBlacklistedError[] =
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Loading of unpacked extensions is disabled by the administrator.";
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Manages an ExtensionInstallPrompt for a particular extension.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SimpleExtensionLoadPrompt : public ExtensionInstallPrompt::Delegate {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SimpleExtensionLoadPrompt(const Extension* extension,
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            Profile* profile,
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const base::Closure& callback);
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~SimpleExtensionLoadPrompt();
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ShowPrompt();
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ExtensionInstallUI::Delegate
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallUIProceed() OVERRIDE;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ExtensionInstallPrompt> install_ui_;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<const Extension> extension_;
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Closure callback_;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SimpleExtensionLoadPrompt::SimpleExtensionLoadPrompt(
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const Extension* extension,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Closure& callback)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : install_ui_(ExtensionInstallUI::CreateInstallPromptWithProfile(
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          profile)),
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extension_(extension),
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      callback_(callback) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SimpleExtensionLoadPrompt::~SimpleExtensionLoadPrompt() {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SimpleExtensionLoadPrompt::ShowPrompt() {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  install_ui_->ConfirmInstall(
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      this,
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      extension_.get(),
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExtensionInstallPrompt::GetDefaultShowDialogCallback());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SimpleExtensionLoadPrompt::InstallUIProceed() {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_.Run();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SimpleExtensionLoadPrompt::InstallUIAbort(bool user_initiated) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<UnpackedInstaller> UnpackedInstaller::Create(
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionService* extension_service) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return scoped_refptr<UnpackedInstaller>(
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new UnpackedInstaller(extension_service));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UnpackedInstaller::UnpackedInstaller(ExtensionService* extension_service)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : service_weak_(extension_service->AsWeakPtr()),
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prompt_for_plugins_(true),
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      require_modern_manifest_version_(true),
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      installer_(extension_service->profile()) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UnpackedInstaller::~UnpackedInstaller() {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::CurrentlyOn(BrowserThread::FILE));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UnpackedInstaller::Load(const base::FilePath& path_in) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(extension_path_.empty());
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_path_ = path_in;
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BrowserThread::PostTask(
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      BrowserThread::FILE,
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&UnpackedInstaller::GetAbsolutePath, this));
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool UnpackedInstaller::LoadFromCommandLine(const base::FilePath& path_in,
117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                            std::string* extension_id) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(extension_path_.empty());
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!service_weak_.get())
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load extensions from the command line synchronously to avoid a race
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // between extension loading and loading an URL from the command line.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ThreadRestrictions::ScopedAllowIO allow_io;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  extension_path_ = base::MakeAbsoluteFilePath(path_in);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsLoadingUnpackedAllowed()) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportExtensionLoadError(kUnpackedExtensionsBlacklistedError);
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  installer_.set_extension(extension_file_util::LoadExtension(
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      extension_path_, Manifest::COMMAND_LINE, GetFlags(), &error).get());
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!installer_.extension().get()) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportExtensionLoadError(error);
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShowInstallPrompt();
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *extension_id = installer_.extension()->id();
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void UnpackedInstaller::ShowInstallPrompt() {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!service_weak_.get())
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const ExtensionSet* disabled_extensions =
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      service_weak_->disabled_extensions();
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (service_weak_->show_extensions_prompts() && prompt_for_plugins_ &&
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      PluginInfo::HasPlugins(installer_.extension().get()) &&
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !disabled_extensions->Contains(installer_.extension()->id())) {
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SimpleExtensionLoadPrompt* prompt = new SimpleExtensionLoadPrompt(
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        installer_.extension().get(),
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        installer_.profile(),
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&UnpackedInstaller::CallCheckRequirements, this));
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    prompt->ShowPrompt();
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallCheckRequirements();
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void UnpackedInstaller::CallCheckRequirements() {
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  installer_.CheckRequirements(
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&UnpackedInstaller::OnRequirementsChecked, this));
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UnpackedInstaller::OnRequirementsChecked(
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> requirement_errors) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!requirement_errors.empty()) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportExtensionLoadError(JoinString(requirement_errors, ' '));
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ConfirmInstall();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int UnpackedInstaller::GetFlags() {
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string id = id_util::GenerateIdForPath(extension_path_);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool allow_file_access =
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Manifest::ShouldAlwaysAllowFileAccess(Manifest::UNPACKED);
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExtensionPrefs* prefs = service_weak_->extension_prefs();
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (prefs->HasAllowFileAccessSetting(id))
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    allow_file_access = prefs->AllowFileAccess(id);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = Extension::FOLLOW_SYMLINKS_ANYWHERE;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (allow_file_access)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result |= Extension::ALLOW_FILE_ACCESS;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (require_modern_manifest_version_)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result |= Extension::REQUIRE_MODERN_MANIFEST_VERSION;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UnpackedInstaller::IsLoadingUnpackedAllowed() const {
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!service_weak_.get())
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there is a "*" in the extension blacklist, then no extensions should be
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allowed at all (except explicitly whitelisted extensions).
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExtensionPrefs* prefs = service_weak_->extension_prefs();
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !prefs->ExtensionsBlacklistedByDefault();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UnpackedInstaller::GetAbsolutePath() {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  extension_path_ = base::MakeAbsoluteFilePath(extension_path_);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BrowserThread::PostTask(
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&UnpackedInstaller::CheckExtensionFileAccess, this));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UnpackedInstaller::CheckExtensionFileAccess() {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!service_weak_.get())
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsLoadingUnpackedAllowed()) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportExtensionLoadError(kUnpackedExtensionsBlacklistedError);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BrowserThread::PostTask(
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      BrowserThread::FILE,
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&UnpackedInstaller::LoadWithFileAccess, this, GetFlags()));
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UnpackedInstaller::LoadWithFileAccess(int flags) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  installer_.set_extension(extension_file_util::LoadExtension(
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      extension_path_, Manifest::UNPACKED, flags, &error).get());
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!installer_.extension().get()) {
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    BrowserThread::PostTask(
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        BrowserThread::UI,
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE,
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&UnpackedInstaller::ReportExtensionLoadError, this, error));
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BrowserThread::PostTask(
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      BrowserThread::UI,
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&UnpackedInstaller::ShowInstallPrompt, this));
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UnpackedInstaller::ReportExtensionLoadError(const std::string &error) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!service_weak_.get())
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_weak_->ReportExtensionLoadError(extension_path_, error, true);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void UnpackedInstaller::ConfirmInstall() {
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  string16 error = installer_.CheckManagementPolicy();
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!error.empty()) {
270a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    ReportExtensionLoadError(UTF16ToUTF8(error));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PermissionsUpdater perms_updater(service_weak_->profile());
2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  perms_updater.GrantActivePermissions(installer_.extension().get());
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  service_weak_->OnExtensionInstalled(
278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      installer_.extension().get(),
279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      syncer::StringOrdinal(),
280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      false /* no requirement errors */,
281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      Blacklist::NOT_BLACKLISTED,
282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      false /* don't wait for idle */);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
286