Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / active_tab_permission_granter.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/active_tab_permission_granter.h"
6
7 #include "chrome/browser/profiles/profile.h"
8 #include "content/public/browser/navigation_details.h"
9 #include "content/public/browser/navigation_entry.h"
10 #include "content/public/browser/web_contents.h"
11 #include "extensions/browser/extension_registry.h"
12 #include "extensions/common/extension_messages.h"
13 #include "extensions/common/permissions/permission_set.h"
14 #include "extensions/common/permissions/permissions_data.h"
15 #include "extensions/common/user_script.h"
16
17 using content::RenderProcessHost;
18 using content::WebContentsObserver;
19
20 namespace extensions {
21
22 ActiveTabPermissionGranter::ActiveTabPermissionGranter(
23     content::WebContents* web_contents,
24     int tab_id,
25     Profile* profile)
26     : WebContentsObserver(web_contents),
27       tab_id_(tab_id),
28       extension_registry_observer_(this) {
29   extension_registry_observer_.Add(ExtensionRegistry::Get(profile));
30 }
31
32 ActiveTabPermissionGranter::~ActiveTabPermissionGranter() {}
33
34 void ActiveTabPermissionGranter::GrantIfRequested(const Extension* extension) {
35   // Active tab grant request implies there was a user gesture.
36   web_contents()->UserGestureDone();
37
38   if (granted_extensions_.Contains(extension->id()))
39     return;
40
41   APIPermissionSet new_apis;
42   URLPatternSet new_hosts;
43
44   if (extension->HasAPIPermission(APIPermission::kActiveTab)) {
45     URLPattern pattern(UserScript::ValidUserScriptSchemes());
46     // Pattern parsing could fail if this is an unsupported URL e.g. chrome://.
47     if (pattern.Parse(web_contents()->GetURL().spec()) ==
48             URLPattern::PARSE_SUCCESS) {
49       new_hosts.AddPattern(pattern);
50     }
51     new_apis.insert(APIPermission::kTab);
52   }
53
54   if (extension->HasAPIPermission(APIPermission::kTabCapture))
55     new_apis.insert(APIPermission::kTabCaptureForTab);
56
57   if (!new_apis.empty() || !new_hosts.is_empty()) {
58     granted_extensions_.Insert(extension);
59     scoped_refptr<const PermissionSet> new_permissions =
60         new PermissionSet(new_apis, ManifestPermissionSet(),
61                           new_hosts, URLPatternSet());
62     PermissionsData::UpdateTabSpecificPermissions(extension,
63                                                   tab_id_,
64                                                   new_permissions);
65     const content::NavigationEntry* navigation_entry =
66         web_contents()->GetController().GetVisibleEntry();
67     if (navigation_entry) {
68       Send(new ExtensionMsg_UpdateTabSpecificPermissions(
69           navigation_entry->GetPageID(),
70           tab_id_,
71           extension->id(),
72           new_hosts));
73     }
74   }
75 }
76
77 void ActiveTabPermissionGranter::DidNavigateMainFrame(
78     const content::LoadCommittedDetails& details,
79     const content::FrameNavigateParams& params) {
80   if (details.is_in_page)
81     return;
82   DCHECK(details.is_main_frame);  // important: sub-frames don't get granted!
83   ClearActiveExtensionsAndNotify();
84 }
85
86 void ActiveTabPermissionGranter::WebContentsDestroyed() {
87   ClearActiveExtensionsAndNotify();
88 }
89
90 void ActiveTabPermissionGranter::OnExtensionUnloaded(
91     content::BrowserContext* browser_context,
92     const Extension* extension,
93     UnloadedExtensionInfo::Reason reason) {
94   // Note: don't need to clear the permissions (nor tell the renderer about it)
95   // because it's being unloaded anyway.
96   granted_extensions_.Remove(extension->id());
97 }
98
99 void ActiveTabPermissionGranter::ClearActiveExtensionsAndNotify() {
100   if (granted_extensions_.is_empty())
101     return;
102
103   std::vector<std::string> extension_ids;
104
105   for (ExtensionSet::const_iterator it = granted_extensions_.begin();
106        it != granted_extensions_.end(); ++it) {
107     PermissionsData::ClearTabSpecificPermissions(it->get(), tab_id_);
108     extension_ids.push_back((*it)->id());
109   }
110
111   Send(new ExtensionMsg_ClearTabSpecificPermissions(tab_id_, extension_ids));
112   granted_extensions_.Clear();
113 }
114
115 }  // namespace extensions