File: on_task_extensions_manager_impl.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (120 lines) | stat: -rw-r--r-- 4,702 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/boca/on_task/on_task_extensions_manager_impl.h"

#include "ash/constants/ash_features.h"
#include "base/functional/bind.h"
#include "base/task/sequenced_task_runner.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chromeos/ash/components/boca/on_task/on_task_prefs.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "extensions/browser/extension_registrar.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/management_policy.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest.h"

using extensions::Extension;
using extensions::ExtensionId;
using extensions::ExtensionIdList;
using extensions::ExtensionRegistrar;
using extensions::ExtensionRegistry;
using extensions::ExtensionSystem;
using extensions::ManagementPolicy;

namespace ash::boca {

OnTaskExtensionsManagerImpl::OnTaskExtensionsManagerImpl(Profile* profile)
    : profile_(profile) {
  // Re-enable extensions on init. This is needed should a device crash or
  // reboot so we can restore extensions to their previous enabled state.
  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
      FROM_HERE,
      base::BindOnce(&OnTaskExtensionsManagerImpl::ReEnableExtensions,
                     weak_ptr_factory_.GetWeakPtr()));
}

OnTaskExtensionsManagerImpl::~OnTaskExtensionsManagerImpl() = default;

void OnTaskExtensionsManagerImpl::DisableExtensions() {
  auto* extension_registrar = ExtensionRegistrar::Get(profile_);
  const ExtensionRegistry* const extension_registry =
      ExtensionRegistry::Get(profile_);
  ExtensionIdList disabled_extension_ids;
  for (const auto& extension_id :
       extension_registry->enabled_extensions().GetIDs()) {
    const Extension* const extension =
        extension_registry->enabled_extensions().GetByID(extension_id);
    if (CanDisableExtension(extension)) {
      // We use `DISABLE_USER_ACTION` disable reason despite its support with
      // extension sync for now. This remains consistent with extension
      // management through the Assessment Assistant extension used with locked
      // quizzes. This may be adjusted for both components accordingly.
      extension_registrar->DisableExtension(
          extension_id, {extensions::disable_reason::DISABLE_USER_ACTION});
      disabled_extension_ids.push_back(extension_id);
    }
  }

  if (disabled_extension_ids.empty()) {
    return;
  }
  SaveDisabledExtensionIds(disabled_extension_ids);
}

void OnTaskExtensionsManagerImpl::ReEnableExtensions() {
  auto* extension_registrar = ExtensionRegistrar::Get(profile_);
  const ExtensionRegistry* const extension_registry =
      ExtensionRegistry::Get(profile_);
  const base::Value::List& disabled_extension_ids =
      profile_->GetPrefs()->GetList(kDisabledOnTaskExtensions);
  for (const auto& disabled_extension_id : disabled_extension_ids) {
    const ExtensionId& extension_id =
        static_cast<ExtensionId>(disabled_extension_id.GetString());
    const Extension* const extension =
        extension_registry->disabled_extensions().GetByID(extension_id);
    if (extension && CanEnableExtension(extension)) {
      extension_registrar->EnableExtension(extension_id);
    }
  }

  // Clear tracked extension ids now that they have been processed.
  SaveDisabledExtensionIds({});
}

bool OnTaskExtensionsManagerImpl::CanDisableExtension(
    const Extension* extension) {
  CHECK(extension);

  bool is_component_extension =
      extensions::Manifest::IsComponentLocation(extension->location());
  const ManagementPolicy* const policy =
      ExtensionSystem::Get(profile_)->management_policy();
  return !is_component_extension &&
         !policy->MustRemainEnabled(extension, /*error=*/nullptr);
}

bool OnTaskExtensionsManagerImpl::CanEnableExtension(
    const Extension* extension) {
  CHECK(extension);
  const ManagementPolicy* const policy =
      ExtensionSystem::Get(profile_)->management_policy();
  return !policy->MustRemainDisabled(extension, /*reason=*/nullptr);
}

void OnTaskExtensionsManagerImpl::SaveDisabledExtensionIds(
    const ExtensionIdList& extension_ids) {
  ScopedListPrefUpdate pref_update(profile_->GetPrefs(),
                                   kDisabledOnTaskExtensions);
  base::Value::List& saved_extension_ids = pref_update.Get();
  saved_extension_ids.clear();
  for (const auto& extension_id : extension_ids) {
    saved_extension_ids.Append(extension_id);
  }
}

}  // namespace ash::boca