Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: ios/shared/chrome/browser/tabs/web_state_list.mm

Issue 2710183003: Fix WebStateListObserver::WebStateDetachedAt() parameter lifetime. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #import "ios/shared/chrome/browser/tabs/web_state_list.h" 5 #import "ios/shared/chrome/browser/tabs/web_state_list.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" 11 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h"
12 #import "ios/web/public/navigation_manager.h" 12 #import "ios/web/public/navigation_manager.h"
13 #import "ios/web/public/web_state/web_state.h" 13 #import "ios/web/public/web_state/web_state.h"
14 14
15 #if !defined(__has_feature) || !__has_feature(objc_arc) 15 #if !defined(__has_feature) || !__has_feature(objc_arc)
16 #error "This file requires ARC support." 16 #error "This file requires ARC support."
17 #endif 17 #endif
18 18
19 // Wrapper around a WebState stored in a WebStateList. May own the WebState 19 // Wrapper around a WebState stored in a WebStateList.
20 // dependending on the WebStateList ownership setting (should always be true
21 // once ownership of Tab is sane, see http://crbug.com/546222 for progress).
22 class WebStateList::WebStateWrapper { 20 class WebStateList::WebStateWrapper {
23 public: 21 public:
24 WebStateWrapper(web::WebState* web_state, bool assume_ownership); 22 WebStateWrapper(web::WebState* web_state);
pkl (ping after 24h if needed) 2017/02/27 19:32:09 I think the style guide mandates "explicit" for si
sdefresne 2017/02/28 05:52:52 Done. Thank you.
25 ~WebStateWrapper(); 23 ~WebStateWrapper();
26 24
27 web::WebState* web_state() const { return web_state_; } 25 web::WebState* web_state() const { return web_state_; }
28 web::WebState* opener() const { return opener_; } 26 web::WebState* opener() const { return opener_; }
29 27
30 // Replaces the wrapped WebState (and clear associated state) and returns the 28 // Replaces the wrapped WebState (and clear associated state) and returns the
31 // old WebState after forfeiting ownership. 29 // old WebState after forfeiting ownership.
32 web::WebState* ReplaceWebState(web::WebState* web_state); 30 web::WebState* ReplaceWebState(web::WebState* web_state);
33 31
34 // Sets the opener for the wrapped WebState and record the opener navigation 32 // Sets the opener for the wrapped WebState and record the opener navigation
35 // index to allow detecting navigation changes during the same session. 33 // index to allow detecting navigation changes during the same session.
36 void SetOpener(web::WebState* opener); 34 void SetOpener(web::WebState* opener);
37 35
38 // Returns whether |opener| spawned the wrapped WebState. If |use_group| is 36 // Returns whether |opener| spawned the wrapped WebState. If |use_group| is
39 // true, also use the opener navigation index to detect navigation changes 37 // true, also use the opener navigation index to detect navigation changes
40 // during the same session. 38 // during the same session.
41 bool WasOpenedBy(const web::WebState* opener, 39 bool WasOpenedBy(const web::WebState* opener,
42 int opener_navigation_index, 40 int opener_navigation_index,
43 bool use_group) const; 41 bool use_group) const;
44 42
45 private: 43 private:
46 web::WebState* web_state_; 44 web::WebState* web_state_;
47 web::WebState* opener_ = nullptr; 45 web::WebState* opener_ = nullptr;
48 int opener_last_committed_index_; 46 int opener_last_committed_index_;
49 const bool has_web_state_ownership_;
50 47
51 DISALLOW_COPY_AND_ASSIGN(WebStateWrapper); 48 DISALLOW_COPY_AND_ASSIGN(WebStateWrapper);
52 }; 49 };
53 50
54 WebStateList::WebStateWrapper::WebStateWrapper(web::WebState* web_state, 51 WebStateList::WebStateWrapper::WebStateWrapper(web::WebState* web_state)
55 bool assume_ownership) 52 : web_state_(web_state) {
56 : web_state_(web_state), has_web_state_ownership_(assume_ownership) {
57 DCHECK(web_state_); 53 DCHECK(web_state_);
58 } 54 }
59 55
60 WebStateList::WebStateWrapper::~WebStateWrapper() { 56 WebStateList::WebStateWrapper::~WebStateWrapper() = default;
61 if (has_web_state_ownership_)
62 delete web_state_;
63 }
64 57
65 web::WebState* WebStateList::WebStateWrapper::ReplaceWebState( 58 web::WebState* WebStateList::WebStateWrapper::ReplaceWebState(
66 web::WebState* web_state) { 59 web::WebState* web_state) {
67 DCHECK(web_state); 60 DCHECK(web_state);
68 DCHECK_NE(web_state, web_state_); 61 DCHECK_NE(web_state, web_state_);
69 std::swap(web_state, web_state_); 62 std::swap(web_state, web_state_);
70 opener_ = nullptr; 63 opener_ = nullptr;
71 return web_state; 64 return web_state;
72 } 65 }
73 66
(...skipping 14 matching lines...) Expand all
88 81
89 if (!use_group) 82 if (!use_group)
90 return true; 83 return true;
91 84
92 return opener_last_committed_index_ == opener_navigation_index; 85 return opener_last_committed_index_ == opener_navigation_index;
93 } 86 }
94 87
95 WebStateList::WebStateList(WebStateOwnership ownership) 88 WebStateList::WebStateList(WebStateOwnership ownership)
96 : web_state_ownership_(ownership) {} 89 : web_state_ownership_(ownership) {}
97 90
98 WebStateList::~WebStateList() = default; 91 WebStateList::~WebStateList() {
92 // Once WebStateList owns the WebState and has a CloseWebStateAt() method,
93 // then change this to close all the WebState. See http://crbug.com/546222
94 // for progress.
95 if (web_state_ownership_ == WebStateOwned) {
96 for (auto& web_state_wrapper : web_state_wrappers_) {
97 web::WebState* web_state = web_state_wrapper->web_state();
98 delete web_state;
99 }
100 }
101 }
99 102
100 bool WebStateList::ContainsIndex(int index) const { 103 bool WebStateList::ContainsIndex(int index) const {
101 return 0 <= index && index < count(); 104 return 0 <= index && index < count();
102 } 105 }
103 106
104 web::WebState* WebStateList::GetWebStateAt(int index) const { 107 web::WebState* WebStateList::GetWebStateAt(int index) const {
105 DCHECK(ContainsIndex(index)); 108 DCHECK(ContainsIndex(index));
106 return web_state_wrappers_[index]->web_state(); 109 return web_state_wrappers_[index]->web_state();
107 } 110 }
108 111
(...skipping 25 matching lines...) Expand all
134 int WebStateList::GetIndexOfLastWebStateOpenedBy(const web::WebState* opener, 137 int WebStateList::GetIndexOfLastWebStateOpenedBy(const web::WebState* opener,
135 int start_index, 138 int start_index,
136 bool use_group) const { 139 bool use_group) const {
137 return GetIndexOfNthWebStateOpenedBy(opener, start_index, use_group, INT_MAX); 140 return GetIndexOfNthWebStateOpenedBy(opener, start_index, use_group, INT_MAX);
138 } 141 }
139 142
140 void WebStateList::InsertWebState(int index, 143 void WebStateList::InsertWebState(int index,
141 web::WebState* web_state, 144 web::WebState* web_state,
142 web::WebState* opener) { 145 web::WebState* opener) {
143 DCHECK(ContainsIndex(index) || index == count()); 146 DCHECK(ContainsIndex(index) || index == count());
144 web_state_wrappers_.insert( 147 web_state_wrappers_.insert(web_state_wrappers_.begin() + index,
145 web_state_wrappers_.begin() + index, 148 base::MakeUnique<WebStateWrapper>(web_state));
146 base::MakeUnique<WebStateWrapper>(web_state,
147 web_state_ownership_ == WebStateOwned));
148 149
149 if (opener) 150 if (opener)
150 SetOpenerOfWebStateAt(index, opener); 151 SetOpenerOfWebStateAt(index, opener);
151 152
152 for (auto& observer : observers_) 153 for (auto& observer : observers_)
153 observer.WebStateInsertedAt(this, web_state, index); 154 observer.WebStateInsertedAt(this, web_state, index);
154 } 155 }
155 156
156 void WebStateList::MoveWebStateAt(int from_index, int to_index) { 157 void WebStateList::MoveWebStateAt(int from_index, int to_index) {
157 DCHECK(ContainsIndex(from_index)); 158 DCHECK(ContainsIndex(from_index));
(...skipping 23 matching lines...) Expand all
181 182
182 if (opener && opener != old_web_state) 183 if (opener && opener != old_web_state)
183 SetOpenerOfWebStateAt(index, opener); 184 SetOpenerOfWebStateAt(index, opener);
184 185
185 for (auto& observer : observers_) 186 for (auto& observer : observers_)
186 observer.WebStateReplacedAt(this, old_web_state, web_state, index); 187 observer.WebStateReplacedAt(this, old_web_state, web_state, index);
187 188
188 return old_web_state; 189 return old_web_state;
189 } 190 }
190 191
191 void WebStateList::DetachWebStateAt(int index) { 192 web::WebState* WebStateList::DetachWebStateAt(int index) {
192 DCHECK(ContainsIndex(index)); 193 DCHECK(ContainsIndex(index));
193 ClearOpenersReferencing(index); 194 ClearOpenersReferencing(index);
194 195
195 web::WebState* web_state = web_state_wrappers_[index]->web_state(); 196 web::WebState* old_web_state = web_state_wrappers_[index]->web_state();
196 web_state_wrappers_.erase(web_state_wrappers_.begin() + index); 197 web_state_wrappers_.erase(web_state_wrappers_.begin() + index);
197 198
198 for (auto& observer : observers_) 199 for (auto& observer : observers_)
199 observer.WebStateDetachedAt(this, web_state, index); 200 observer.WebStateDetachedAt(this, old_web_state, index);
201
202 return old_web_state;
200 } 203 }
201 204
202 void WebStateList::AddObserver(WebStateListObserver* observer) { 205 void WebStateList::AddObserver(WebStateListObserver* observer) {
203 observers_.AddObserver(observer); 206 observers_.AddObserver(observer);
204 } 207 }
205 208
206 void WebStateList::RemoveObserver(WebStateListObserver* observer) { 209 void WebStateList::RemoveObserver(WebStateListObserver* observer) {
207 observers_.RemoveObserver(observer); 210 observers_.RemoveObserver(observer);
208 } 211 }
209 212
(...skipping 25 matching lines...) Expand all
235 } else if (found_index != kInvalidIndex) { 238 } else if (found_index != kInvalidIndex) {
236 return found_index; 239 return found_index;
237 } 240 }
238 } 241 }
239 242
240 return found_index; 243 return found_index;
241 } 244 }
242 245
243 // static 246 // static
244 const int WebStateList::kInvalidIndex; 247 const int WebStateList::kInvalidIndex;
OLDNEW
« no previous file with comments | « ios/shared/chrome/browser/tabs/web_state_list.h ('k') | ios/shared/chrome/browser/tabs/web_state_list_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698