OLD | NEW |
| (Empty) |
1 // Copyright 2014 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/push_messaging/push_messaging_permission_context.h" | |
6 | |
7 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | |
8 #include "chrome/browser/permissions/permission_manager.h" | |
9 #include "chrome/browser/permissions/permission_request_id.h" | |
10 #include "chrome/browser/permissions/permission_uma_util.h" | |
11 #include "chrome/browser/profiles/profile.h" | |
12 #include "components/content_settings/core/browser/host_content_settings_map.h" | |
13 #include "content/public/browser/browser_thread.h" | |
14 #include "content/public/browser/permission_type.h" | |
15 #include "content/public/browser/web_contents.h" | |
16 #include "content/public/browser/web_contents_delegate.h" | |
17 #include "content/public/common/origin_util.h" | |
18 | |
19 PushMessagingPermissionContext::PushMessagingPermissionContext(Profile* profile) | |
20 : PermissionContextBase(profile, | |
21 content::PermissionType::PUSH_MESSAGING, | |
22 CONTENT_SETTINGS_TYPE_PUSH_MESSAGING), | |
23 profile_(profile), | |
24 weak_factory_ui_thread_(this) {} | |
25 | |
26 PushMessagingPermissionContext::~PushMessagingPermissionContext() {} | |
27 | |
28 ContentSetting PushMessagingPermissionContext::GetPermissionStatus( | |
29 const GURL& requesting_origin, | |
30 const GURL& embedding_origin) const { | |
31 // It's possible for this to return CONTENT_SETTING_BLOCK in cases where | |
32 // HostContentSettingsMap::GetContentSetting returns CONTENT_SETTING_ALLOW. | |
33 // TODO(johnme): This is likely to break assumptions made elsewhere, so we | |
34 // should try to remove this quirk. | |
35 #if defined(ENABLE_NOTIFICATIONS) | |
36 if (requesting_origin != embedding_origin) | |
37 return CONTENT_SETTING_BLOCK; | |
38 | |
39 ContentSetting push_content_setting = | |
40 PermissionContextBase::GetPermissionStatus(requesting_origin, | |
41 embedding_origin); | |
42 | |
43 blink::mojom::PermissionStatus notifications_permission = | |
44 PermissionManager::Get(profile_)->GetPermissionStatus( | |
45 content::PermissionType::NOTIFICATIONS, requesting_origin, | |
46 embedding_origin); | |
47 | |
48 if (notifications_permission == blink::mojom::PermissionStatus::DENIED || | |
49 push_content_setting == CONTENT_SETTING_BLOCK) { | |
50 return CONTENT_SETTING_BLOCK; | |
51 } | |
52 if (notifications_permission == blink::mojom::PermissionStatus::ASK) | |
53 return CONTENT_SETTING_ASK; | |
54 | |
55 DCHECK(push_content_setting == CONTENT_SETTING_ALLOW || | |
56 push_content_setting == CONTENT_SETTING_ASK); | |
57 | |
58 // If the notifications permission has already been granted, | |
59 // and the push permission isn't explicitly blocked, then grant | |
60 // allow permission. | |
61 return CONTENT_SETTING_ALLOW; | |
62 #else | |
63 return CONTENT_SETTING_BLOCK; | |
64 #endif | |
65 } | |
66 | |
67 // Unlike other permissions, push is decided by the following algorithm | |
68 // - You need to request it from a top level domain | |
69 // - You need to have notification permission granted. | |
70 // - You need to not have push permission explicitly blocked. | |
71 // - If those 3 things are true it is granted without prompting. | |
72 // This is done to avoid double prompting for notifications and push. | |
73 void PushMessagingPermissionContext::DecidePermission( | |
74 content::WebContents* web_contents, | |
75 const PermissionRequestID& id, | |
76 const GURL& requesting_origin, | |
77 const GURL& embedding_origin, | |
78 bool user_gesture, | |
79 const BrowserPermissionCallback& callback) { | |
80 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
81 #if defined(ENABLE_NOTIFICATIONS) | |
82 if (requesting_origin != embedding_origin) { | |
83 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, | |
84 false /* persist */, CONTENT_SETTING_BLOCK); | |
85 return; | |
86 } | |
87 | |
88 PermissionManager::Get(profile_)->RequestPermission( | |
89 content::PermissionType::NOTIFICATIONS, web_contents->GetMainFrame(), | |
90 requesting_origin, user_gesture, | |
91 base::Bind(&PushMessagingPermissionContext::DecidePushPermission, | |
92 weak_factory_ui_thread_.GetWeakPtr(), id, requesting_origin, | |
93 embedding_origin, callback)); | |
94 #else | |
95 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, | |
96 false /* persist */, CONTENT_SETTING_BLOCK); | |
97 #endif | |
98 } | |
99 | |
100 bool PushMessagingPermissionContext::IsRestrictedToSecureOrigins() const { | |
101 return true; | |
102 } | |
103 | |
104 void PushMessagingPermissionContext::DecidePushPermission( | |
105 const PermissionRequestID& id, | |
106 const GURL& requesting_origin, | |
107 const GURL& embedding_origin, | |
108 const BrowserPermissionCallback& callback, | |
109 blink::mojom::PermissionStatus notification_status) { | |
110 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
111 DCHECK_NE(notification_status, blink::mojom::PermissionStatus::ASK); | |
112 | |
113 ContentSetting push_content_setting = | |
114 HostContentSettingsMapFactory::GetForProfile(profile_) | |
115 ->GetContentSettingAndMaybeUpdateLastUsage( | |
116 requesting_origin, embedding_origin, content_settings_type(), | |
117 std::string()); | |
118 | |
119 if (push_content_setting == CONTENT_SETTING_BLOCK) { | |
120 DVLOG(1) << "Push permission was explicitly blocked."; | |
121 PermissionUmaUtil::PermissionDenied(permission_type(), requesting_origin, | |
122 profile_); | |
123 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, | |
124 true /* persist */, CONTENT_SETTING_BLOCK); | |
125 return; | |
126 } | |
127 | |
128 if (notification_status == blink::mojom::PermissionStatus::DENIED) { | |
129 DVLOG(1) << "Notification permission has not been granted."; | |
130 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, | |
131 false /* persist */, CONTENT_SETTING_BLOCK); | |
132 return; | |
133 } | |
134 | |
135 PermissionUmaUtil::PermissionGranted(permission_type(), requesting_origin, | |
136 profile_); | |
137 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, | |
138 true /* persist */, CONTENT_SETTING_ALLOW); | |
139 } | |
OLD | NEW |