OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/push_messaging/push_messaging_notification_manager.h" | 5 #include "chrome/browser/push_messaging/push_messaging_notification_manager.h" |
6 | 6 |
7 #include <bitset> | 7 #include <bitset> |
8 | 8 |
9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 const base::Closure& message_handled_closure, | 134 const base::Closure& message_handled_closure, |
135 bool success, | 135 bool success, |
136 const std::vector<NotificationDatabaseData>& data) { | 136 const std::vector<NotificationDatabaseData>& data) { |
137 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 137 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
138 // TODO(johnme): Hiding an existing notification should also count as a useful | 138 // TODO(johnme): Hiding an existing notification should also count as a useful |
139 // user-visible action done in response to a push message - but make sure that | 139 // user-visible action done in response to a push message - but make sure that |
140 // sending two messages in rapid succession which show then hide a | 140 // sending two messages in rapid succession which show then hide a |
141 // notification doesn't count. | 141 // notification doesn't count. |
142 int notification_count = success ? data.size() : 0; | 142 int notification_count = success ? data.size() : 0; |
143 bool notification_shown = notification_count > 0; | 143 bool notification_shown = notification_count > 0; |
144 | |
145 bool notification_needed = true; | 144 bool notification_needed = true; |
146 | 145 |
147 // Sites with a currently visible tab don't need to show notifications. | 146 // Sites with a currently visible tab don't need to show notifications. |
148 | |
149 #if defined(OS_ANDROID) | 147 #if defined(OS_ANDROID) |
150 for (auto it = TabModelList::begin(); it != TabModelList::end(); ++it) { | 148 for (auto it = TabModelList::begin(); it != TabModelList::end(); ++it) { |
151 Profile* profile = (*it)->GetProfile(); | 149 Profile* profile = (*it)->GetProfile(); |
152 WebContents* active_web_contents = (*it)->GetActiveWebContents(); | 150 WebContents* active_web_contents = (*it)->GetActiveWebContents(); |
153 #else | 151 #else |
154 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | 152 for (chrome::BrowserIterator it; !it.done(); it.Next()) { |
155 Profile* profile = it->profile(); | 153 Profile* profile = it->profile(); |
156 WebContents* active_web_contents = | 154 WebContents* active_web_contents = |
157 it->tab_strip_model()->GetActiveWebContents(); | 155 it->tab_strip_model()->GetActiveWebContents(); |
158 #endif | 156 #endif |
159 if (!active_web_contents || !active_web_contents->GetMainFrame()) | 157 if (IsTabVisible(profile, active_web_contents, origin)) { |
160 continue; | |
161 | |
162 // Don't leak information from other profiles. | |
163 if (profile != profile_) | |
164 continue; | |
165 | |
166 // Ignore minimized windows etc. | |
167 switch (active_web_contents->GetMainFrame()->GetVisibilityState()) { | |
168 case blink::WebPageVisibilityStateHidden: | |
169 case blink::WebPageVisibilityStatePrerender: | |
170 continue; | |
171 case blink::WebPageVisibilityStateVisible: | |
172 break; | |
173 } | |
174 | |
175 // Use the visible URL since that's the one the user is aware of (and it | |
176 // doesn't matter whether the page loaded successfully). | |
177 const GURL& active_url = active_web_contents->GetVisibleURL(); | |
178 if (origin == active_url.GetOrigin()) { | |
179 notification_needed = false; | 158 notification_needed = false; |
180 break; | 159 break; |
181 } | 160 } |
182 #if defined(OS_ANDROID) | 161 #if defined(OS_ANDROID) |
183 } | 162 } |
184 #else | 163 #else |
185 } | 164 } |
186 #endif | 165 #endif |
187 | 166 |
188 // If more than one notification is showing for this Service Worker, close | 167 // If more than one notification is showing for this Service Worker, close |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 weak_factory_.GetWeakPtr(), origin, | 201 weak_factory_.GetWeakPtr(), origin, |
223 service_worker_registration_id, notification_shown, | 202 service_worker_registration_id, notification_shown, |
224 notification_needed, message_handled_closure)); | 203 notification_needed, message_handled_closure)); |
225 } else { | 204 } else { |
226 RecordUserVisibleStatus( | 205 RecordUserVisibleStatus( |
227 content::PUSH_USER_VISIBLE_STATUS_NOT_REQUIRED_AND_NOT_SHOWN); | 206 content::PUSH_USER_VISIBLE_STATUS_NOT_REQUIRED_AND_NOT_SHOWN); |
228 message_handled_closure.Run(); | 207 message_handled_closure.Run(); |
229 } | 208 } |
230 } | 209 } |
231 | 210 |
| 211 bool PushMessagingNotificationManager::IsTabVisible( |
| 212 Profile* profile, |
| 213 WebContents* active_web_contents, |
| 214 const GURL& origin) { |
| 215 if (!active_web_contents || !active_web_contents->GetMainFrame()) |
| 216 return false; |
| 217 |
| 218 // Don't leak information from other profiles. |
| 219 if (profile != profile_) |
| 220 return false; |
| 221 |
| 222 // Ignore minimized windows. |
| 223 switch (active_web_contents->GetMainFrame()->GetVisibilityState()) { |
| 224 case blink::WebPageVisibilityStateHidden: |
| 225 case blink::WebPageVisibilityStatePrerender: |
| 226 return false; |
| 227 case blink::WebPageVisibilityStateVisible: |
| 228 break; |
| 229 } |
| 230 |
| 231 // Use the visible URL since that's the one the user is aware of (and it |
| 232 // doesn't matter whether the page loaded successfully). |
| 233 return origin == active_web_contents->GetVisibleURL().GetOrigin(); |
| 234 } |
| 235 |
232 void PushMessagingNotificationManager::DidGetNotificationsShownAndNeeded( | 236 void PushMessagingNotificationManager::DidGetNotificationsShownAndNeeded( |
233 const GURL& origin, | 237 const GURL& origin, |
234 int64_t service_worker_registration_id, | 238 int64_t service_worker_registration_id, |
235 bool notification_shown, | 239 bool notification_shown, |
236 bool notification_needed, | 240 bool notification_needed, |
237 const base::Closure& message_handled_closure, | 241 const base::Closure& message_handled_closure, |
238 const std::string& data, | 242 const std::string& data, |
239 bool success, | 243 bool success, |
240 bool not_found) { | 244 bool not_found) { |
241 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 245 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 message_handled_closure.Run(); | 334 message_handled_closure.Run(); |
331 return; | 335 return; |
332 } | 336 } |
333 | 337 |
334 PlatformNotificationServiceImpl::GetInstance()->DisplayPersistentNotification( | 338 PlatformNotificationServiceImpl::GetInstance()->DisplayPersistentNotification( |
335 profile_, persistent_notification_id, origin, SkBitmap() /* icon */, | 339 profile_, persistent_notification_id, origin, SkBitmap() /* icon */, |
336 notification_data); | 340 notification_data); |
337 | 341 |
338 message_handled_closure.Run(); | 342 message_handled_closure.Run(); |
339 } | 343 } |
OLD | NEW |