Commit 05788069 authored by Peter Kasting's avatar Peter Kasting Committed by Commit Bot

Simplify AwFormDatabaseService interaction with AutofillWebDataService.

The AutofillWebDataService APIs can be consumed on any thread, not just the DB
thread, so it's not necessary to post to the DB thread to call them.

The AwFormDatabaseService itself is only accessed on one thread, and blocks
while it has an ongoing HasFormData() call, so there can't be multiple requests
in-flight at once.  This lets us remove the entire result map.

Bug: None
Change-Id: I7b6cd5272cb569d00fcd4cc6f89f22082100184c
Reviewed-on: https://chromium-review.googlesource.com/578298
Commit-Queue: Peter Kasting <pkasting@chromium.org>
Reviewed-by: default avatarSelim Gurun <sgurun@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488163}
parent 51a27f03
......@@ -4,9 +4,10 @@
#include "android_webview/browser/aw_form_database_service.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/webdata/common/webdata_constants.h"
......@@ -28,7 +29,11 @@ void DatabaseErrorCallback(sql::InitStatus init_status,
namespace android_webview {
AwFormDatabaseService::AwFormDatabaseService(const base::FilePath path) {
AwFormDatabaseService::AwFormDatabaseService(const base::FilePath path)
: has_form_data_result_(false),
has_form_data_completion_(
base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
web_database_ = new WebDatabaseService(
path.Append(kWebDataFilename),
......@@ -50,7 +55,6 @@ AwFormDatabaseService::~AwFormDatabaseService() {
void AwFormDatabaseService::Shutdown() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(result_map_.empty());
// TODO(sgurun) we don't run into this logic right now,
// but if we do, then we need to implement cancellation
// of pending queries.
......@@ -64,14 +68,6 @@ AwFormDatabaseService::get_autofill_webdata_service() {
}
void AwFormDatabaseService::ClearFormData() {
BrowserThread::PostTask(
BrowserThread::DB,
FROM_HERE,
base::Bind(&AwFormDatabaseService::ClearFormDataImpl,
base::Unretained(this)));
}
void AwFormDatabaseService::ClearFormDataImpl() {
base::Time begin;
base::Time end = base::Time::Max();
autofill_data_->RemoveFormElementsAddedBetween(begin, end);
......@@ -79,57 +75,30 @@ void AwFormDatabaseService::ClearFormDataImpl() {
}
bool AwFormDatabaseService::HasFormData() {
WaitableEvent completion(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
bool result = false;
BrowserThread::PostTask(
BrowserThread::DB,
has_form_data_result_ = false;
has_form_data_completion_.Reset();
using awds = autofill::AutofillWebDataService;
base::PostTask(
FROM_HERE,
base::Bind(&AwFormDatabaseService::HasFormDataImpl,
base::Unretained(this),
&completion,
&result));
base::Bind(base::IgnoreResult(&awds::GetCountOfValuesContainedBetween),
autofill_data_, base::Time(), base::Time::Max(), this));
{
base::ThreadRestrictions::ScopedAllowWait wait;
completion.Wait();
has_form_data_completion_.Wait();
}
return result;
}
void AwFormDatabaseService::HasFormDataImpl(
WaitableEvent* completion,
bool* result) {
WebDataServiceBase::Handle pending_query_handle =
autofill_data_->GetCountOfValuesContainedBetween(
base::Time(), base::Time::Max(), this);
PendingQuery query;
query.result = result;
query.completion = completion;
result_map_[pending_query_handle] = query;
return has_form_data_result_;
}
void AwFormDatabaseService::OnWebDataServiceRequestDone(
WebDataServiceBase::Handle h,
std::unique_ptr<WDTypedResult> result) {
DCHECK_CURRENTLY_ON(BrowserThread::DB);
bool has_form_data = false;
if (result) {
DCHECK_EQ(AUTOFILL_VALUE_RESULT, result->GetType());
const WDResult<int>* autofill_result =
static_cast<const WDResult<int>*>(result.get());
has_form_data = autofill_result->GetValue() > 0;
}
QueryMap::const_iterator it = result_map_.find(h);
if (it == result_map_.end()) {
LOG(WARNING) << "Received unexpected callback from web data service";
return;
has_form_data_result_ = autofill_result->GetValue() > 0;
}
WaitableEvent* completion = it->second.completion;
*(it->second.result) = has_form_data;
result_map_.erase(h);
completion->Signal();
has_form_data_completion_.Signal();
}
} // namespace android_webview
......@@ -7,14 +7,11 @@
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/synchronization/waitable_event.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/webdata/common/web_data_service_consumer.h"
#include "components/webdata/common/web_database_service.h"
namespace base {
class WaitableEvent;
};
namespace android_webview {
// Handles the database operations necessary to implement the autocomplete
......@@ -45,16 +42,8 @@ class AwFormDatabaseService : public WebDataServiceConsumer {
std::unique_ptr<WDTypedResult> result) override;
private:
struct PendingQuery {
bool* result;
base::WaitableEvent* completion;
};
typedef std::map<WebDataServiceBase::Handle, PendingQuery> QueryMap;
void ClearFormDataImpl();
void HasFormDataImpl(base::WaitableEvent* completion, bool* result);
QueryMap result_map_;
bool has_form_data_result_;
base::WaitableEvent has_form_data_completion_;
scoped_refptr<autofill::AutofillWebDataService> autofill_data_;
scoped_refptr<WebDatabaseService> web_database_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment