blob: 6b5f7d85c1f6d9f474f0590d079dc463c050e66b [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ash/accessibility/accessibility_extension_loader.h"
#include "base/callback.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "extensions/browser/extension_system.h"
namespace ash {
AccessibilityExtensionLoader::AccessibilityExtensionLoader(
const std::string& extension_id,
const base::FilePath& extension_path,
const base::FilePath::CharType* manifest_filename,
const base::FilePath::CharType* guest_manifest_filename,
const base::Closure& unload_callback)
: profile_(nullptr),
extension_id_(extension_id),
extension_path_(extension_path),
manifest_filename_(manifest_filename),
guest_manifest_filename_(guest_manifest_filename),
loaded_(false),
unload_callback_(unload_callback) {}
AccessibilityExtensionLoader::~AccessibilityExtensionLoader() = default;
void AccessibilityExtensionLoader::SetProfile(
Profile* profile,
const base::Closure& done_callback) {
Profile* prev_profile = profile_;
profile_ = profile;
if (!loaded_)
return;
// If the extension was loaded on the previous profile (which isn't the
// current profile), unload it there.
if (prev_profile && prev_profile != profile)
UnloadExtensionFromProfile(prev_profile);
// If the extension was already enabled, but not for this profile, add it
// to this profile.
auto* extension_service =
extensions::ExtensionSystem::Get(profile_)->extension_service();
auto* component_loader = extension_service->component_loader();
if (!component_loader->Exists(extension_id_))
LoadExtension(profile_, done_callback);
}
void AccessibilityExtensionLoader::Load(Profile* profile,
const base::Closure& done_cb) {
profile_ = profile;
if (loaded_)
return;
loaded_ = true;
LoadExtension(profile_, done_cb);
}
void AccessibilityExtensionLoader::Unload() {
if (loaded_) {
UnloadExtensionFromProfile(profile_);
UnloadExtensionFromProfile(ProfileHelper::GetSigninProfile());
loaded_ = false;
}
profile_ = nullptr;
if (unload_callback_)
unload_callback_.Run();
}
//
// private
//
void AccessibilityExtensionLoader::UnloadExtensionFromProfile(
Profile* profile) {
extensions::ExtensionService* extension_service =
extensions::ExtensionSystem::Get(profile)->extension_service();
extension_service->component_loader()->Remove(extension_id_);
}
void AccessibilityExtensionLoader::LoadExtension(Profile* profile,
base::Closure done_cb) {
// In Kiosk mode, we should reinstall the extension upon first load. This way,
// no state from the previous session is preserved.
user_manager::User* user = ProfileHelper::Get()->GetUserByProfile(profile);
base::Closure closure = done_cb;
if (user && user->IsKioskType() && !was_reset_for_kiosk_) {
was_reset_for_kiosk_ = true;
extensions::ExtensionService* extension_service =
extensions::ExtensionSystem::Get(profile)->extension_service();
extension_service->DisableExtension(
extension_id_, extensions::disable_reason::DISABLE_REINSTALL);
closure = base::BindRepeating(
&AccessibilityExtensionLoader::ReinstallExtensionForKiosk,
weak_ptr_factory_.GetWeakPtr(), profile, done_cb);
}
LoadExtensionImpl(profile, closure);
}
void AccessibilityExtensionLoader::LoadExtensionImpl(Profile* profile,
base::Closure done_cb) {
DCHECK(manifest_filename_);
DCHECK(guest_manifest_filename_);
extensions::ExtensionService* extension_service =
extensions::ExtensionSystem::Get(profile)->extension_service();
extension_service->component_loader()
->AddComponentFromDirWithManifestFilename(
extension_path_, extension_id_.c_str(), manifest_filename_,
guest_manifest_filename_, done_cb);
}
void AccessibilityExtensionLoader::ReinstallExtensionForKiosk(
Profile* profile,
base::Closure done_cb) {
DCHECK(was_reset_for_kiosk_);
auto* extension_service =
extensions::ExtensionSystem::Get(profile)->extension_service();
std::u16string error;
extension_service->UninstallExtension(
extension_id_, extensions::UninstallReason::UNINSTALL_REASON_REINSTALL,
&error);
extension_service->component_loader()->Reload(extension_id_);
if (done_cb)
done_cb.Run();
}
} // namespace ash