OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/history/android/sqlite_cursor.h" | 5 #include "chrome/browser/history/android/sqlite_cursor.h" |
6 | 6 |
7 #include "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
8 #include "base/android/jni_array.h" | 8 #include "base/android/jni_array.h" |
9 #include "base/android/jni_string.h" | 9 #include "base/android/jni_string.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 | 125 |
126 event_.Wait(); | 126 event_.Wait(); |
127 return position_; | 127 return position_; |
128 } | 128 } |
129 | 129 |
130 jint SQLiteCursor::GetColumnType(JNIEnv* env, jobject obj, jint column) { | 130 jint SQLiteCursor::GetColumnType(JNIEnv* env, jobject obj, jint column) { |
131 return GetColumnTypeInternal(column); | 131 return GetColumnTypeInternal(column); |
132 } | 132 } |
133 | 133 |
134 void SQLiteCursor::Destroy(JNIEnv* env, jobject obj) { | 134 void SQLiteCursor::Destroy(JNIEnv* env, jobject obj) { |
135 delete this; | 135 // We do our best to cleanup when Destroy() is called from Java's finalize() |
| 136 // where the UI message loop might stop running or in the process of shutting |
| 137 // down, as the whole process will be destroyed soon, it's fine to leave some |
| 138 // objects out there. |
| 139 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 140 DestroyOnUIThread(); |
| 141 } else if (!BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 142 base::Bind(&SQLiteCursor::DestroyOnUIThread, |
| 143 base::Unretained(this)))) { |
| 144 delete this; |
| 145 } |
136 } | 146 } |
137 | 147 |
138 SQLiteCursor::SQLiteCursor(const std::vector<std::string>& column_names, | 148 SQLiteCursor::SQLiteCursor(const std::vector<std::string>& column_names, |
139 history::AndroidStatement* statement, | 149 history::AndroidStatement* statement, |
140 AndroidHistoryProviderService* service, | 150 AndroidHistoryProviderService* service, |
141 FaviconService* favicon_service) | 151 FaviconService* favicon_service) |
142 : position_(-1), | 152 : position_(-1), |
143 event_(false, false), | 153 event_(false, false), |
144 statement_(statement), | 154 statement_(statement), |
145 column_names_(column_names), | 155 column_names_(column_names), |
146 service_(service), | 156 service_(service), |
147 favicon_service_(favicon_service), | 157 favicon_service_(favicon_service), |
148 count_(-1), | 158 count_(-1), |
149 test_observer_(NULL) { | 159 test_observer_(NULL) { |
150 } | 160 } |
151 | 161 |
152 SQLiteCursor::~SQLiteCursor() { | 162 SQLiteCursor::~SQLiteCursor() { |
| 163 } |
| 164 |
| 165 void SQLiteCursor::DestroyOnUIThread() { |
153 // Consumer requests were set in the UI thread. They must be cancelled | 166 // Consumer requests were set in the UI thread. They must be cancelled |
154 // using the same thread. | 167 // using the same thread. |
155 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
156 CancelAllRequests(NULL); | 169 consumer_.reset(); |
157 } else { | 170 tracker_.reset(); |
158 base::WaitableEvent event(false, false); | 171 service_->CloseStatement(statement_); |
159 BrowserThread::PostTask( | 172 delete this; |
160 BrowserThread::UI, | |
161 FROM_HERE, | |
162 base::Bind(&SQLiteCursor::CancelAllRequests, base::Unretained(this), | |
163 &event)); | |
164 event.Wait(); | |
165 } | |
166 | |
167 BrowserThread::PostTask( | |
168 BrowserThread::UI, | |
169 FROM_HERE, | |
170 base::Bind(&AndroidHistoryProviderService::CloseStatement, | |
171 base::Unretained(service_), statement_)); | |
172 } | 173 } |
173 | 174 |
174 bool SQLiteCursor::GetFavicon(chrome::FaviconID id, | 175 bool SQLiteCursor::GetFavicon(chrome::FaviconID id, |
175 std::vector<unsigned char>* image_data) { | 176 std::vector<unsigned char>* image_data) { |
176 if (id) { | 177 if (id) { |
177 BrowserThread::PostTask( | 178 BrowserThread::PostTask( |
178 BrowserThread::UI, | 179 BrowserThread::UI, |
179 FROM_HERE, | 180 FROM_HERE, |
180 base::Bind(&SQLiteCursor::GetFaviconForIDInUIThread, | 181 base::Bind(&SQLiteCursor::GetFaviconForIDInUIThread, |
181 base::Unretained(this), id, | 182 base::Unretained(this), id, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 | 220 |
220 void SQLiteCursor::OnMoved(AndroidHistoryProviderService::Handle handle, | 221 void SQLiteCursor::OnMoved(AndroidHistoryProviderService::Handle handle, |
221 int pos) { | 222 int pos) { |
222 position_ = pos; | 223 position_ = pos; |
223 event_.Signal(); | 224 event_.Signal(); |
224 if (test_observer_) | 225 if (test_observer_) |
225 // Notified test_observer on UI thread instead of the one it will wait. | 226 // Notified test_observer on UI thread instead of the one it will wait. |
226 test_observer_->OnGetMoveToResult(); | 227 test_observer_->OnGetMoveToResult(); |
227 } | 228 } |
228 | 229 |
229 void SQLiteCursor::CancelAllRequests(base::WaitableEvent* finished) { | |
230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
231 | |
232 // Destruction will cancel all pending tasks. | |
233 consumer_.reset(); | |
234 tracker_.reset(); | |
235 | |
236 if (finished) | |
237 finished->Signal(); | |
238 } | |
239 | |
240 SQLiteCursor::JavaColumnType SQLiteCursor::GetColumnTypeInternal(int column) { | 230 SQLiteCursor::JavaColumnType SQLiteCursor::GetColumnTypeInternal(int column) { |
241 if (column == statement_->favicon_index()) | 231 if (column == statement_->favicon_index()) |
242 return SQLiteCursor::BLOB; | 232 return SQLiteCursor::BLOB; |
243 | 233 |
244 return ToJavaColumnType(statement_->statement()->ColumnType(column)); | 234 return ToJavaColumnType(statement_->statement()->ColumnType(column)); |
245 } | 235 } |
246 | 236 |
247 void SQLiteCursor::RunMoveStatementOnUIThread(int pos) { | 237 void SQLiteCursor::RunMoveStatementOnUIThread(int pos) { |
248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
249 if (!consumer_.get()) | 239 if (!consumer_.get()) |
250 consumer_.reset(new CancelableRequestConsumer()); | 240 consumer_.reset(new CancelableRequestConsumer()); |
251 service_->MoveStatement( | 241 service_->MoveStatement( |
252 statement_, position_, pos, consumer_.get(), | 242 statement_, position_, pos, consumer_.get(), |
253 base::Bind(&SQLiteCursor::OnMoved, base::Unretained(this))); | 243 base::Bind(&SQLiteCursor::OnMoved, base::Unretained(this))); |
254 } | 244 } |
OLD | NEW |