| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/data_use_measurement/chrome_data_use_ascriber.h" | 5 #include "chrome/browser/data_use_measurement/chrome_data_use_ascriber.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" |
| 8 #include "components/data_use_measurement/core/data_use_recorder.h" |
| 9 #include "components/data_use_measurement/core/data_use_user_data.h" |
| 7 #include "content/public/browser/browser_thread.h" | 10 #include "content/public/browser/browser_thread.h" |
| 8 #include "content/public/browser/navigation_handle.h" | 11 #include "content/public/browser/navigation_handle.h" |
| 9 #include "content/public/browser/render_frame_host.h" | 12 #include "content/public/browser/render_frame_host.h" |
| 13 #include "content/public/browser/resource_request_info.h" |
| 14 #include "content/public/common/browser_side_navigation_policy.h" |
| 15 #include "net/url_request/url_request.h" |
| 10 | 16 |
| 11 namespace data_use_measurement { | 17 namespace data_use_measurement { |
| 12 | 18 |
| 19 // static |
| 20 const void* ChromeDataUseAscriber::DataUseRecorderEntryAsUserData:: |
| 21 kUserDataKey = static_cast<void*>( |
| 22 &ChromeDataUseAscriber::DataUseRecorderEntryAsUserData::kUserDataKey); |
| 23 |
| 24 ChromeDataUseAscriber::DataUseRecorderEntryAsUserData:: |
| 25 DataUseRecorderEntryAsUserData(DataUseRecorderEntry entry) |
| 26 : entry_(entry) {} |
| 27 |
| 28 ChromeDataUseAscriber::DataUseRecorderEntryAsUserData:: |
| 29 ~DataUseRecorderEntryAsUserData() {} |
| 30 |
| 13 ChromeDataUseAscriber::ChromeDataUseAscriber() { | 31 ChromeDataUseAscriber::ChromeDataUseAscriber() { |
| 14 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 32 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 15 } | 33 } |
| 16 | 34 |
| 17 ChromeDataUseAscriber::~ChromeDataUseAscriber() { | 35 ChromeDataUseAscriber::~ChromeDataUseAscriber() { |
| 18 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 36 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 37 DCHECK_EQ(0u, data_use_recorders_.size()); |
| 19 } | 38 } |
| 20 | 39 |
| 21 DataUseRecorder* ChromeDataUseAscriber::GetDataUseRecorder( | 40 DataUseRecorder* ChromeDataUseAscriber::GetDataUseRecorder( |
| 22 net::URLRequest* request) { | 41 net::URLRequest* request) { |
| 23 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 42 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 24 return nullptr; | 43 return nullptr; |
| 25 } | 44 } |
| 26 | 45 |
| 46 void ChromeDataUseAscriber::OnBeforeUrlRequest(net::URLRequest* request) { |
| 47 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 48 |
| 49 // TODO(kundaji): Handle PlzNavigate. |
| 50 if (content::IsBrowserSideNavigationEnabled()) |
| 51 return; |
| 52 |
| 53 auto service = static_cast<DataUseUserData*>( |
| 54 request->GetUserData(DataUseUserData::kUserDataKey)); |
| 55 if (service) |
| 56 return; |
| 57 |
| 58 const content::ResourceRequestInfo* request_info = |
| 59 content::ResourceRequestInfo::ForRequest(request); |
| 60 content::ResourceType resource_type = request_info |
| 61 ? request_info->GetResourceType() |
| 62 : content::RESOURCE_TYPE_LAST_TYPE; |
| 63 |
| 64 if (resource_type != content::RESOURCE_TYPE_MAIN_FRAME) |
| 65 return; |
| 66 |
| 67 int render_process_id = -1; |
| 68 int render_frame_id = -1; |
| 69 bool has_valid_render_frame_id = |
| 70 content::ResourceRequestInfo::GetRenderFrameForRequest( |
| 71 request, &render_process_id, &render_frame_id); |
| 72 DCHECK(has_valid_render_frame_id); |
| 73 // Browser tests may not set up DataUseWebContentsObservers in which case |
| 74 // this class never sees navigation and frame events so DataUseRecorders |
| 75 // will never be destroyed. To avoid this, we ignore requests whose |
| 76 // render frames don't have a record. However, this can also be caused by |
| 77 // URLRequests racing the frame create events. |
| 78 // TODO(kundaji): Add UMA. |
| 79 if (render_frame_data_use_map_.find( |
| 80 RenderFrameHostID(render_process_id, render_frame_id)) == |
| 81 render_frame_data_use_map_.end()) { |
| 82 return; |
| 83 } |
| 84 |
| 85 // If this request is already being tracked, do not create a new entry. |
| 86 auto user_data = static_cast<DataUseRecorderEntryAsUserData*>( |
| 87 request->GetUserData(DataUseRecorderEntryAsUserData::kUserDataKey)); |
| 88 if (user_data) |
| 89 return; |
| 90 |
| 91 DataUseRecorderEntry entry = data_use_recorders_.insert( |
| 92 data_use_recorders_.end(), base::MakeUnique<DataUseRecorder>()); |
| 93 request->SetUserData(DataUseRecorderEntryAsUserData::kUserDataKey, |
| 94 new DataUseRecorderEntryAsUserData(entry)); |
| 95 pending_navigation_data_use_map_.insert( |
| 96 std::make_pair(request_info->GetGlobalRequestID(), entry)); |
| 97 } |
| 98 |
| 99 void ChromeDataUseAscriber::OnUrlRequestCompleted(net::URLRequest* request, |
| 100 bool started) { |
| 101 const content::ResourceRequestInfo* request_info = |
| 102 content::ResourceRequestInfo::ForRequest(request); |
| 103 content::ResourceType resource_type = request_info |
| 104 ? request_info->GetResourceType() |
| 105 : content::RESOURCE_TYPE_LAST_TYPE; |
| 106 if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME) { |
| 107 // If request was not successful, then ReadyToCommitNavigation will not be |
| 108 // called. So delete the pending navigation DataUseRecorderEntry here. |
| 109 if (!request->status().is_success()) { |
| 110 DeletePendingNavigationEntry(request_info->GetGlobalRequestID()); |
| 111 } |
| 112 } |
| 113 } |
| 114 |
| 27 void ChromeDataUseAscriber::RenderFrameCreated(int render_process_id, | 115 void ChromeDataUseAscriber::RenderFrameCreated(int render_process_id, |
| 28 int render_frame_id, | 116 int render_frame_id, |
| 29 int parent_render_process_id, | 117 int parent_render_process_id, |
| 30 int parent_render_frame_id) { | 118 int parent_render_frame_id) { |
| 31 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 119 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 120 |
| 121 // TODO(kundaji): Point child render frames to the same DataUseRecorder as |
| 122 // parent render frame. |
| 123 DataUseRecorderEntry entry = data_use_recorders_.insert( |
| 124 data_use_recorders_.end(), base::MakeUnique<DataUseRecorder>()); |
| 125 render_frame_data_use_map_.insert(std::make_pair( |
| 126 RenderFrameHostID(render_process_id, render_frame_id), entry)); |
| 32 } | 127 } |
| 33 | 128 |
| 34 void ChromeDataUseAscriber::RenderFrameDeleted(int render_process_id, | 129 void ChromeDataUseAscriber::RenderFrameDeleted(int render_process_id, |
| 35 int render_frame_id, | 130 int render_frame_id, |
| 36 int parent_render_process_id, | 131 int parent_render_process_id, |
| 37 int parent_render_frame_id) { | 132 int parent_render_frame_id) { |
| 38 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 133 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 134 RenderFrameHostID key(render_process_id, render_frame_id); |
| 135 auto frame_iter = render_frame_data_use_map_.find(key); |
| 136 DCHECK(frame_iter != render_frame_data_use_map_.end()); |
| 137 DataUseRecorderEntry entry = frame_iter->second; |
| 138 render_frame_data_use_map_.erase(frame_iter); |
| 139 |
| 140 data_use_recorders_.erase(entry); |
| 39 } | 141 } |
| 40 | 142 |
| 41 void ChromeDataUseAscriber::DidStartMainFrameNavigation( | 143 void ChromeDataUseAscriber::DidStartMainFrameNavigation( |
| 42 GURL gurl, | 144 GURL gurl, |
| 43 int render_process_id, | 145 int render_process_id, |
| 44 int render_frame_id, | 146 int render_frame_id, |
| 45 void* navigation_handle) { | 147 void* navigation_handle) { |
| 46 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 148 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 47 } | 149 } |
| 48 | 150 |
| 49 void ChromeDataUseAscriber::DidFinishMainFrameNavigation( | 151 void ChromeDataUseAscriber::ReadyToCommitMainFrameNavigation( |
| 50 GURL gurl, | 152 GURL gurl, |
| 153 content::GlobalRequestID global_request_id, |
| 51 int render_process_id, | 154 int render_process_id, |
| 52 int render_frame_id, | 155 int render_frame_id, |
| 53 bool is_same_page_navigation, | 156 bool is_same_page_navigation, |
| 54 void* navigation_handle) { | 157 void* navigation_handle) { |
| 55 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 158 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 159 |
| 160 // TODO(kundaji): Move the DataUseRecorderEntry from pending navigation map |
| 161 // to render frame map if |is_same_page_navigation| is true. Otherwise, |
| 162 // merge it with the DataUseRecorderEntry in the render frame map. |
| 163 DeletePendingNavigationEntry(global_request_id); |
| 56 } | 164 } |
| 57 | 165 |
| 58 void ChromeDataUseAscriber::DidRedirectMainFrameNavigation( | 166 void ChromeDataUseAscriber::DidRedirectMainFrameNavigation( |
| 59 GURL gurl, | 167 GURL gurl, |
| 60 int render_process_id, | 168 int render_process_id, |
| 61 int render_frame_id, | 169 int render_frame_id, |
| 62 void* navigation_handle) { | 170 void* navigation_handle) { |
| 63 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 171 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 64 } | 172 } |
| 65 | 173 |
| 174 void ChromeDataUseAscriber::DeletePendingNavigationEntry( |
| 175 content::GlobalRequestID global_request_id) { |
| 176 auto navigation_iter = |
| 177 pending_navigation_data_use_map_.find(global_request_id); |
| 178 // Pending navigation entry will not be found if finish navigation |
| 179 // raced the URLRequest. |
| 180 if (navigation_iter != pending_navigation_data_use_map_.end()) { |
| 181 auto entry = navigation_iter->second; |
| 182 pending_navigation_data_use_map_.erase(navigation_iter); |
| 183 data_use_recorders_.erase(entry); |
| 184 } |
| 185 } |
| 186 |
| 66 } // namespace data_use_measurement | 187 } // namespace data_use_measurement |
| OLD | NEW |