Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/page_load_metrics/observers/ads_page_load_metrics_obser ver.h" | 5 #include "chrome/browser/page_load_metrics/observers/ads_page_load_metrics_obser ver.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/feature_list.h" | 10 #include "base/feature_list.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 49 return true; | 49 return true; |
| 50 } | 50 } |
| 51 } | 51 } |
| 52 | 52 |
| 53 const GURL& url = navigation_handle->GetURL(); | 53 const GURL& url = navigation_handle->GetURL(); |
| 54 return url.host_piece() == "tpc.googlesyndication.com" && | 54 return url.host_piece() == "tpc.googlesyndication.com" && |
| 55 base::StartsWith(url.path_piece(), "/safeframe", | 55 base::StartsWith(url.path_piece(), "/safeframe", |
| 56 base::CompareCase::SENSITIVE); | 56 base::CompareCase::SENSITIVE); |
| 57 } | 57 } |
| 58 | 58 |
| 59 void RecordParentExistsForSubFrame(bool parent_exists) { | |
| 60 UMA_HISTOGRAM_BOOLEAN("PageLoad.Clients.Ads.Google.ParentExistsForSubFrame", | |
| 61 parent_exists); | |
| 62 } | |
| 63 | |
| 59 } // namespace | 64 } // namespace |
| 60 | 65 |
| 61 AdsPageLoadMetricsObserver::AdFrameData::AdFrameData( | 66 AdsPageLoadMetricsObserver::AdFrameData::AdFrameData( |
| 62 FrameTreeNodeId frame_tree_node_id) | 67 FrameTreeNodeId frame_tree_node_id) |
| 63 : frame_bytes(0u), | 68 : frame_bytes(0u), |
| 64 frame_bytes_uncached(0u), | 69 frame_bytes_uncached(0u), |
| 65 frame_tree_node_id(frame_tree_node_id) {} | 70 frame_tree_node_id(frame_tree_node_id) {} |
| 66 | 71 |
| 67 // static | 72 // static |
| 68 std::unique_ptr<AdsPageLoadMetricsObserver> | 73 std::unique_ptr<AdsPageLoadMetricsObserver> |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 // This frame was previously not an ad, process it as usual. If it had | 120 // This frame was previously not an ad, process it as usual. If it had |
| 116 // any child frames that were ads, those will still be recorded. | 121 // any child frames that were ads, those will still be recorded. |
| 117 UMA_HISTOGRAM_BOOLEAN( | 122 UMA_HISTOGRAM_BOOLEAN( |
| 118 "PageLoad.Clients.Ads.Google.Navigations.NonAdFrameRenavigatedToAd", | 123 "PageLoad.Clients.Ads.Google.Navigations.NonAdFrameRenavigatedToAd", |
| 119 FrameIsAd(navigation_handle)); | 124 FrameIsAd(navigation_handle)); |
| 120 } | 125 } |
| 121 | 126 |
| 122 // Determine who the parent frame's ad ancestor is. | 127 // Determine who the parent frame's ad ancestor is. |
| 123 const auto& parent_id_and_data = | 128 const auto& parent_id_and_data = |
| 124 ad_frames_data_.find(parent_frame_host->GetFrameTreeNodeId()); | 129 ad_frames_data_.find(parent_frame_host->GetFrameTreeNodeId()); |
| 125 DCHECK(parent_id_and_data != ad_frames_data_.end()); | 130 if (parent_id_and_data == ad_frames_data_.end()) { |
| 131 // We don't know who the parent for this frame is. One possibility is that | |
| 132 // it's a frame from a previous navigation. | |
| 133 RecordParentExistsForSubFrame(false /* parent_exists */); | |
| 134 | |
| 135 return CONTINUE_OBSERVING; | |
| 136 } | |
| 137 RecordParentExistsForSubFrame(true /* parent_exists */); | |
| 138 | |
| 126 AdFrameData* ad_data = parent_id_and_data->second; | 139 AdFrameData* ad_data = parent_id_and_data->second; |
| 127 | 140 |
| 128 if (!ad_data && FrameIsAd(navigation_handle)) { | 141 if (!ad_data && FrameIsAd(navigation_handle)) { |
| 129 // This frame is not nested within an ad frame but is itself an ad. | 142 // This frame is not nested within an ad frame but is itself an ad. |
| 130 ad_frames_data_storage_.emplace_back(frame_tree_node_id); | 143 ad_frames_data_storage_.emplace_back(frame_tree_node_id); |
| 131 ad_data = &ad_frames_data_storage_.back(); | 144 ad_data = &ad_frames_data_storage_.back(); |
| 132 } | 145 } |
| 133 | 146 |
| 134 ad_frames_data_[frame_tree_node_id] = ad_data; | 147 ad_frames_data_[frame_tree_node_id] = ad_data; |
| 135 | 148 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 166 // Data uris should be accounted for in the generating resource, not | 179 // Data uris should be accounted for in the generating resource, not |
| 167 // here. Blobs for PlzNavigate shouldn't be counted as the http resource | 180 // here. Blobs for PlzNavigate shouldn't be counted as the http resource |
| 168 // was already counted. Blobs for other things like CacheStorage or | 181 // was already counted. Blobs for other things like CacheStorage or |
| 169 // IndexedDB are also ignored for now, as they're not normal HTTP loads. | 182 // IndexedDB are also ignored for now, as they're not normal HTTP loads. |
| 170 return; | 183 return; |
| 171 } | 184 } |
| 172 | 185 |
| 173 const auto& id_and_data = | 186 const auto& id_and_data = |
| 174 ad_frames_data_.find(extra_request_info.frame_tree_node_id); | 187 ad_frames_data_.find(extra_request_info.frame_tree_node_id); |
| 175 if (id_and_data == ad_frames_data_.end()) { | 188 if (id_and_data == ad_frames_data_.end()) { |
| 176 // This resource is for a frame that hasn't ever finished a navigation. We | 189 if (extra_request_info.resource_type == content::RESOURCE_TYPE_MAIN_FRAME || |
| 177 // expect it to be the frame's main resource but don't have enough | 190 extra_request_info.resource_type == content::RESOURCE_TYPE_SUB_FRAME) { |
| 178 // confidence in that to dcheck it. For example, there might be races | 191 // This resource request is the primary resource load for a frame that |
| 179 // between doc.written resources and navigation failure. | 192 // hasn't yet finished navigating. Hang onto the request info and replay |
| 180 // TODO(jkarlin): Add UMA to measure how often we see multiple resources | 193 // it once the frame finishes navigating. |
| 181 // for a frame before navigation finishes. | 194 ongoing_navigation_resources_.emplace( |
| 182 ongoing_navigation_resources_.emplace( | 195 std::piecewise_construct, |
| 183 std::piecewise_construct, | 196 std::forward_as_tuple(extra_request_info.frame_tree_node_id), |
| 184 std::forward_as_tuple(extra_request_info.frame_tree_node_id), | 197 std::forward_as_tuple( |
| 185 std::forward_as_tuple( | 198 extra_request_info.url, extra_request_info.frame_tree_node_id, |
| 186 extra_request_info.url, extra_request_info.frame_tree_node_id, | 199 extra_request_info.was_cached, extra_request_info.raw_body_bytes, |
| 187 extra_request_info.was_cached, extra_request_info.raw_body_bytes, | 200 extra_request_info.original_network_content_length, nullptr, |
| 188 extra_request_info.original_network_content_length, nullptr, | 201 extra_request_info.resource_type)); |
| 189 extra_request_info.resource_type)); | 202 UMA_HISTOGRAM_ENUMERATION( |
| 203 "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", | |
|
Bryan McQuade
2017/05/16 17:28:39
ah, sorry, didn't realize this was already varying
jkarlin
2017/05/16 17:33:59
Done.
| |
| 204 extra_request_info.resource_type, content::RESOURCE_TYPE_LAST_TYPE); | |
| 205 } else { | |
| 206 // This is unexpected, it could be: | |
| 207 // 1. a resource from a previous navigation that started its resource | |
| 208 // load after this page started navigation. | |
| 209 // 2. possibly a resource from a document.written frame whose frame | |
| 210 // failure message has yet to arrive. (uncertain of this) | |
| 211 UMA_HISTOGRAM_ENUMERATION( | |
| 212 "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", | |
| 213 extra_request_info.resource_type, content::RESOURCE_TYPE_LAST_TYPE); | |
| 214 } | |
| 190 return; | 215 return; |
| 191 } | 216 } |
| 192 | 217 |
| 193 page_bytes_ += extra_request_info.raw_body_bytes; | 218 page_bytes_ += extra_request_info.raw_body_bytes; |
| 194 if (!extra_request_info.was_cached) | 219 if (!extra_request_info.was_cached) |
| 195 uncached_page_bytes_ += extra_request_info.raw_body_bytes; | 220 uncached_page_bytes_ += extra_request_info.raw_body_bytes; |
| 196 | 221 |
| 197 // Determine if the frame (or its ancestor) is an ad, if so attribute the | 222 // Determine if the frame (or its ancestor) is an ad, if so attribute the |
| 198 // bytes to the highest ad ancestor. | 223 // bytes to the highest ad ancestor. |
| 199 AdFrameData* ancestor_data = id_and_data->second; | 224 AdFrameData* ancestor_data = id_and_data->second; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 void AdsPageLoadMetricsObserver::ProcessOngoingNavigationResource( | 302 void AdsPageLoadMetricsObserver::ProcessOngoingNavigationResource( |
| 278 FrameTreeNodeId frame_tree_node_id) { | 303 FrameTreeNodeId frame_tree_node_id) { |
| 279 const auto& frame_id_and_request = | 304 const auto& frame_id_and_request = |
| 280 ongoing_navigation_resources_.find(frame_tree_node_id); | 305 ongoing_navigation_resources_.find(frame_tree_node_id); |
| 281 if (frame_id_and_request == ongoing_navigation_resources_.end()) | 306 if (frame_id_and_request == ongoing_navigation_resources_.end()) |
| 282 return; | 307 return; |
| 283 | 308 |
| 284 ProcessLoadedResource(frame_id_and_request->second); | 309 ProcessLoadedResource(frame_id_and_request->second); |
| 285 ongoing_navigation_resources_.erase(frame_id_and_request); | 310 ongoing_navigation_resources_.erase(frame_id_and_request); |
| 286 } | 311 } |
| OLD | NEW |