summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extension_util.cc
blob: 890d8d1392c9051afcaac0bf99df3a1fdda112d3 (plain)
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
121
122
123
124
125
126
127
// Copyright 2013 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/extensions/extension_util.h"

#include "base/command_line.h"
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_sync_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/incognito_handler.h"
#include "chrome/common/extensions/sync_helper.h"
#include "extensions/common/manifest.h"

using extensions::Extension;
using extensions::ExtensionPrefs;

namespace extension_util {

bool IsIncognitoEnabled(const std::string& extension_id,
                        const ExtensionService* service) {
  if (!service)
    return false;

  const Extension* extension = service->GetInstalledExtension(extension_id);
  if (extension && !extension->can_be_incognito_enabled())
    return false;
  // If this is an existing component extension we always allow it to
  // work in incognito mode.
  if (extension && extension->location() == extensions::Manifest::COMPONENT)
    return true;
  if (extension && extension->force_incognito_enabled())
    return true;

  // Check the prefs.
  return service->extension_prefs()->IsIncognitoEnabled(extension_id);
}

void SetIsIncognitoEnabled(const std::string& extension_id,
                           ExtensionService* service,
                           bool enabled) {
  const Extension* extension = service->GetInstalledExtension(extension_id);
  if (extension && !extension->can_be_incognito_enabled())
    return;
  if (extension && extension->location() == extensions::Manifest::COMPONENT) {
    // This shouldn't be called for component extensions unless it is called
    // by sync, for syncable component extensions.
    // See http://crbug.com/112290 and associated CLs for the sordid history.
    DCHECK(extensions::sync_helper::IsSyncable(extension));

    // If we are here, make sure the we aren't trying to change the value.
    DCHECK_EQ(enabled, IsIncognitoEnabled(extension_id, service));
    return;
  }

  ExtensionPrefs* extension_prefs = service->extension_prefs();
  // Broadcast unloaded and loaded events to update browser state. Only bother
  // if the value changed and the extension is actually enabled, since there is
  // no UI otherwise.
  bool old_enabled = extension_prefs->IsIncognitoEnabled(extension_id);
  if (enabled == old_enabled)
    return;

  extension_prefs->SetIsIncognitoEnabled(extension_id, enabled);

  bool extension_is_enabled = service->extensions()->Contains(extension_id);

  // When we reload the extension the ID may be invalidated if we've passed it
  // by const ref everywhere. Make a copy to be safe.
  std::string id = extension_id;
  if (extension_is_enabled)
    service->ReloadExtension(id);

  // Reloading the extension invalidates the |extension| pointer.
  extension = service->GetInstalledExtension(id);
  if (extension) {
    ExtensionSyncService::Get(service->profile())->
        SyncExtensionChangeIfNeeded(*extension);
  }
}

bool CanCrossIncognito(const Extension* extension,
                       const ExtensionService* service) {
  // We allow the extension to see events and data from another profile iff it
  // uses "spanning" behavior and it has incognito access. "split" mode
  // extensions only see events for a matching profile.
  CHECK(extension);
  return extension_util::IsIncognitoEnabled(extension->id(), service) &&
         !extensions::IncognitoInfo::IsSplitMode(extension);
}

bool CanLoadInIncognito(const Extension* extension,
                        const ExtensionService* service) {
  if (extension->is_hosted_app())
    return true;
  // Packaged apps and regular extensions need to be enabled specifically for
  // incognito (and split mode should be set).
  return extensions::IncognitoInfo::IsSplitMode(extension) &&
         extension_util::IsIncognitoEnabled(extension->id(), service);
}

bool AllowFileAccess(const Extension* extension,
                     const ExtensionService* service) {
  return (CommandLine::ForCurrentProcess()->HasSwitch(
              switches::kDisableExtensionsFileAccessCheck) ||
          service->extension_prefs()->AllowFileAccess(extension->id()));
}

void SetAllowFileAccess(const Extension* extension,
                        ExtensionService* service,
                        bool allow) {
  // Reload to update browser state. Only bother if the value changed and the
  // extension is actually enabled, since there is no UI otherwise.
  bool old_allow = AllowFileAccess(extension, service);
  if (allow == old_allow)
    return;

  service->extension_prefs()->SetAllowFileAccess(extension->id(), allow);

  bool extension_is_enabled = service->extensions()->Contains(extension->id());
  if (extension_is_enabled)
    service->ReloadExtension(extension->id());
}

}  // namespace extension_util