summaryrefslogtreecommitdiffstats
path: root/chrome/browser/webdata
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/webdata')
-rw-r--r--chrome/browser/webdata/web_data_service.cc55
-rw-r--r--chrome/browser/webdata/web_data_service.h36
-rw-r--r--chrome/browser/webdata/web_database.cc247
-rw-r--r--chrome/browser/webdata/web_database.h43
4 files changed, 375 insertions, 6 deletions
diff --git a/chrome/browser/webdata/web_data_service.cc b/chrome/browser/webdata/web_data_service.cc
index fd0e60a..002977c 100644
--- a/chrome/browser/webdata/web_data_service.cc
+++ b/chrome/browser/webdata/web_data_service.cc
@@ -13,6 +13,7 @@
#include "chrome/browser/template_url.h"
#include "chrome/common/chrome_constants.h"
#include "webkit/glue/password_form.h"
+#include "webkit/glue/autofill_form.h"
////////////////////////////////////////////////////////////////////////////////
//
@@ -114,6 +115,33 @@ void WebDataService::CancelRequest(Handle h) {
i->second->Cancel();
}
+void WebDataService::AddAutofillFormElements(
+ const std::vector<AutofillForm::Element>& element) {
+ GenericRequest<std::vector<AutofillForm::Element> >* request =
+ new GenericRequest<std::vector<AutofillForm::Element> >(
+ this, GetNextRequestHandle(), NULL, element);
+ RegisterRequest(request);
+ ScheduleTask(NewRunnableMethod(this,
+ &WebDataService::AddAutofillFormElementsImpl,
+ request));
+}
+
+WebDataService::Handle WebDataService::GetFormValuesForElementName(
+ const std::wstring& name, const std::wstring& prefix, int limit,
+ WebDataServiceConsumer* consumer) {
+ WebDataRequest* request =
+ new WebDataRequest(this, GetNextRequestHandle(), consumer);
+ RegisterRequest(request);
+ ScheduleTask(
+ NewRunnableMethod(this,
+ &WebDataService::GetFormValuesForElementNameImpl,
+ request,
+ name,
+ prefix,
+ limit));
+ return request->GetHandle();
+}
+
void WebDataService::RequestCompleted(Handle h) {
pending_lock_.Acquire();
RequestMap::iterator i = pending_requests_.find(h);
@@ -562,6 +590,33 @@ void WebDataService::GetAllLoginsImpl(WebDataRequest* request) {
////////////////////////////////////////////////////////////////////////////////
//
+// Autofill support.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+void WebDataService::AddAutofillFormElementsImpl(
+ GenericRequest<std::vector<AutofillForm::Element> >* request) {
+ if (db_ && !request->IsCancelled()) {
+ if (db_->AddAutofillFormElements(request->GetArgument()))
+ ScheduleCommit();
+ }
+ request->RequestComplete();
+}
+
+void WebDataService::GetFormValuesForElementNameImpl(WebDataRequest* request,
+ const std::wstring& name, const std::wstring& prefix, int limit) {
+ if (db_ && !request->IsCancelled()) {
+ std::vector<std::wstring> values;
+ db_->GetFormValuesForElementName(name, prefix, &values, limit);
+ request->SetResult(
+ new WDResult<std::vector<std::wstring> >(AUTOFILL_VALUE_RESULT,
+ values));
+ }
+ request->RequestComplete();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
// Web Apps implementation.
//
////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/webdata/web_data_service.h b/chrome/browser/webdata/web_data_service.h
index 25a4e27..86a7af88 100644
--- a/chrome/browser/webdata/web_data_service.h
+++ b/chrome/browser/webdata/web_data_service.h
@@ -14,9 +14,11 @@
#include "chrome/common/scoped_vector.h"
#include <map>
-class GURL;
-struct PasswordForm;
+struct AutofillForm::Element;
struct IE7PasswordInfo;
+struct PasswordForm;
+class AutofillForm;
+class GURL;
class ShutdownTask;
class TemplateURL;
@@ -46,6 +48,7 @@ typedef enum {
PASSWORD_RESULT, // WDResult<std::vector<PasswordForm*>>
PASSWORD_IE7_RESULT, // WDResult<IE7PasswordInfo>
WEB_APP_IMAGES, // WDResult<WDAppImagesResult>
+ AUTOFILL_VALUE_RESULT, // WDResult<std::vector<std::wstring>>
} WDResultType;
// Result from GetWebAppImages.
@@ -350,6 +353,25 @@ class WebDataService : public base::RefCountedThreadSafe<WebDataService> {
// WebDataServiceConsumer is about to be deleted.
void CancelRequest(Handle h);
+ //////////////////////////////////////////////////////////////////////////////
+ //
+ // Autofill.
+ //
+ //////////////////////////////////////////////////////////////////////////////
+
+ // Schedules a task to add form elements to the web database.
+ void AddAutofillFormElements(
+ const std::vector<AutofillForm::Element>& elements);
+
+ // Initiates the request for a vector of values which have been entered in
+ // form input fields named |name|. The method OnWebDataServiceRequestDone of
+ // |consumer| gets called back when the request is finished, with the vector
+ // included in the argument |result|.
+ Handle GetFormValuesForElementName(const std::wstring& name,
+ const std::wstring& prefix,
+ int limit,
+ WebDataServiceConsumer* consumer);
+
protected:
friend class TemplateURLModelTest;
friend class TemplateURLModelTestingProfile;
@@ -416,6 +438,16 @@ class WebDataService : public base::RefCountedThreadSafe<WebDataService> {
//////////////////////////////////////////////////////////////////////////////
//
+ // Autofill.
+ //
+ //////////////////////////////////////////////////////////////////////////////
+ void AddAutofillFormElementsImpl(
+ GenericRequest<std::vector<AutofillForm::Element> >* request);
+ void GetFormValuesForElementNameImpl(WebDataRequest* request,
+ const std::wstring& name, const std::wstring& prefix, int limit);
+
+ //////////////////////////////////////////////////////////////////////////////
+ //
// Web Apps.
//
//////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/webdata/web_database.cc b/chrome/browser/webdata/web_database.cc
index dca2924..c22990c 100644
--- a/chrome/browser/webdata/web_database.cc
+++ b/chrome/browser/webdata/web_database.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/ie7_password.h"
#include "chrome/browser/template_url.h"
#include "chrome/browser/encryptor.h"
+#include "chrome/common/l10n_util.h"
#include "chrome/common/scoped_vector.h"
#include "webkit/glue/password_form.h"
@@ -61,6 +62,21 @@
// remember'
// passwords for this site.
//
+// autofill
+// name The name of the input as specified in the html.
+// value The literal contents of the text field.
+// value_lower The contents of the text field made lower_case.
+// pair_id An ID number unique to the row in the table.
+// count How many times the user has entered the string |value|
+// in a field of name |name|.
+//
+// autofill_dates This table associates a row to each separate time the
+// user submits a form containing a certain name/value
+// pair. The |pair_id| should match the |pair_id| field
+// in the appropriate row of the autofill table.
+// pair_id
+// date_created
+//
// web_app_icons
// url URL of the web app.
// width Width of the image.
@@ -161,7 +177,8 @@ bool WebDatabase::Init(const std::wstring& db_name) {
// Initialize the tables.
if (!InitKeywordsTable() || !InitLoginsTable() || !InitWebAppIconsTable() ||
- !InitWebAppsTable()) {
+ !InitWebAppsTable() || !InitAutofillTable() ||
+ !InitAutofillDatesTable()) {
LOG(WARNING) << "Unable to initialize the web database.";
return false;
}
@@ -345,6 +362,58 @@ bool WebDatabase::InitLoginsTable() {
return true;
}
+bool WebDatabase::InitAutofillTable() {
+ if (!DoesSqliteTableExist(db_, "autofill")) {
+ if (sqlite3_exec(db_,
+ "CREATE TABLE autofill ("
+ "name VARCHAR, "
+ "value VARCHAR, "
+ "value_lower VARCHAR, "
+ "pair_id INTEGER PRIMARY KEY, "
+ "count INTEGER DEFAULT 1)",
+ NULL, NULL, NULL) != SQLITE_OK) {
+ NOTREACHED();
+ return false;
+ }
+ if (sqlite3_exec(db_,
+ "CREATE INDEX autofill_name ON "
+ "autofill (name)",
+ NULL, NULL, NULL) != SQLITE_OK) {
+ NOTREACHED();
+ return false;
+ }
+ if (sqlite3_exec(db_,
+ "CREATE INDEX autofill_name_value_lower ON "
+ "autofill (name, value_lower)",
+ NULL, NULL, NULL) != SQLITE_OK) {
+ NOTREACHED();
+ return false;
+ }
+ }
+ return true;
+}
+
+bool WebDatabase::InitAutofillDatesTable() {
+ if (!DoesSqliteTableExist(db_, "autofill_dates")) {
+ if (sqlite3_exec(db_,
+ "CREATE TABLE autofill_dates ( "
+ "pair_id INTEGER DEFAULT 0, "
+ "date_created INTEGER DEFAULT 0)",
+ NULL, NULL, NULL) != SQLITE_OK) {
+ NOTREACHED();
+ return false;
+ }
+ if (sqlite3_exec(db_,
+ "CREATE INDEX autofill_dates_pair_id ON "
+ "autofill (pair_id)",
+ NULL, NULL, NULL) != SQLITE_OK) {
+ NOTREACHED();
+ return false;
+ }
+ }
+ return true;
+}
+
bool WebDatabase::InitWebAppIconsTable() {
if (!DoesSqliteTableExist(db_, "web_app_icons")) {
if (sqlite3_exec(db_, "CREATE TABLE web_app_icons ("
@@ -457,7 +526,7 @@ bool WebDatabase::GetKeywords(std::vector<TemplateURL*>* urls) {
NOTREACHED() << "Statement prepare failed";
return false;
}
- int64 result;
+ int result;
while ((result = s.step()) == SQLITE_ROW) {
TemplateURL* template_url = new TemplateURL();
std::wstring tmp;
@@ -791,7 +860,7 @@ bool WebDatabase::GetLogins(const PasswordForm& form,
s.bind_string(0, form.signon_realm);
- int64 result;
+ int result;
while ((result = s.step()) == SQLITE_ROW) {
PasswordForm* new_form = new PasswordForm();
InitPasswordFormFromStatement(new_form, &s);
@@ -842,7 +911,7 @@ bool WebDatabase::GetAllLogins(std::vector<PasswordForm*>* forms,
return false;
}
- int64 result;
+ int result;
while ((result = s.step()) == SQLITE_ROW) {
PasswordForm* new_form = new PasswordForm();
InitPasswordFormFromStatement(new_form, &s);
@@ -852,6 +921,176 @@ bool WebDatabase::GetAllLogins(std::vector<PasswordForm*>* forms,
return result == SQLITE_DONE;
}
+bool WebDatabase::AddAutofillFormElements(
+ const std::vector<AutofillForm::Element>& elements) {
+ bool result = true;
+ for (std::vector<AutofillForm::Element>::const_iterator
+ itr = elements.begin();
+ itr != elements.end();
+ itr++) {
+ result = result && AddAutofillFormElement(*itr);
+ }
+ return result;
+}
+
+bool WebDatabase::GetIDAndCountOfFormElement(
+ const AutofillForm::Element& element, int64* pair_id, int* count) {
+ SQLStatement s;
+
+ if (s.prepare(db_, "SELECT pair_id, count FROM autofill "
+ " WHERE name = ? AND value = ?") != SQLITE_OK) {
+ NOTREACHED() << "Statement prepare failed";
+ return false;
+ }
+
+ s.bind_wstring(0, element.name);
+ s.bind_wstring(1, element.value);
+
+ int result;
+
+ *count = 0;
+
+ if ((result = s.step()) == SQLITE_ROW) {
+ *pair_id = s.column_int64(0);
+ *count = s.column_int(1);
+ }
+
+ return true;
+}
+
+bool WebDatabase::InsertFormElement(const AutofillForm::Element& element,
+ int64* pair_id) {
+ SQLStatement s;
+
+ if (s.prepare(db_, "INSERT INTO autofill "
+ "(name, value, value_lower) "
+ "VALUES (?, ?, ?)")
+ != SQLITE_OK) {
+ NOTREACHED() << "Statement prepare failed";
+ return false;
+ }
+
+ s.bind_wstring(0, element.name);
+ s.bind_wstring(1, element.value);
+ s.bind_wstring(2, l10n_util::ToLower(element.value));
+
+ if (s.step() != SQLITE_DONE) {
+ NOTREACHED();
+ return false;
+ }
+
+ *pair_id = sqlite3_last_insert_rowid(db_);
+
+ return true;
+}
+
+bool WebDatabase::InsertPairIDAndDate(int64 pair_id,
+ const Time& date_created) {
+ SQLStatement s;
+
+ if (s.prepare(db_,
+ "INSERT INTO autofill_dates "
+ "(pair_id, date_created) VALUES (?, ?)")
+ != SQLITE_OK) {
+ NOTREACHED() << "Statement prepare failed";
+ return false;
+ }
+
+ s.bind_int64(0, pair_id);
+ s.bind_int64(1, date_created.ToTimeT());
+
+ if (s.step() != SQLITE_DONE) {
+ NOTREACHED();
+ return false;
+ }
+
+ return true;
+}
+
+bool WebDatabase::SetCountOfFormElement(int64 pair_id, int count) {
+ SQLStatement s;
+
+ if (s.prepare(db_,
+ "UPDATE autofill SET count = ? "
+ "WHERE pair_id = ?")
+ != SQLITE_OK) {
+ NOTREACHED() << "Statement prepare failed";
+ return false;
+ }
+
+ s.bind_int(0, count);
+ s.bind_int64(1, pair_id);
+
+ if (s.step() != SQLITE_DONE) {
+ NOTREACHED();
+ return false;
+ }
+
+ return true;
+}
+
+bool WebDatabase::AddAutofillFormElement(const AutofillForm::Element& element) {
+ SQLStatement s;
+ int count = 0;
+ int64 pair_id;
+
+ if (!GetIDAndCountOfFormElement(element, &pair_id, &count))
+ return false;
+
+ if (count == 0 && !InsertFormElement(element, &pair_id))
+ return false;
+
+ return SetCountOfFormElement(pair_id, count + 1) &&
+ InsertPairIDAndDate(pair_id, Time::Now());
+}
+
+bool WebDatabase::GetFormValuesForElementName(const std::wstring& name,
+ const std::wstring& prefix,
+ std::vector<std::wstring>* values,
+ int limit) {
+ DCHECK(values);
+ SQLStatement s;
+
+ if (prefix.empty()) {
+ if (s.prepare(db_, "SELECT value FROM autofill "
+ "WHERE name = ? "
+ "ORDER BY count DESC "
+ "LIMIT ?") != SQLITE_OK) {
+ NOTREACHED() << "Statement prepare failed";
+ return false;
+ }
+
+ s.bind_wstring(0, name);
+ s.bind_int(1, limit);
+ } else {
+ std::wstring prefix_lower = l10n_util::ToLower(prefix);
+ std::wstring next_prefix = prefix_lower;
+ next_prefix[next_prefix.length() - 1]++;
+
+ if (s.prepare(db_, "SELECT value FROM autofill "
+ "WHERE name = ? AND "
+ "value_lower >= ? AND "
+ "value_lower < ? "
+ "ORDER BY count DESC "
+ "LIMIT ?") != SQLITE_OK) {
+ NOTREACHED() << "Statement prepare failed";
+ return false;
+ }
+
+ s.bind_wstring(0, name);
+ s.bind_wstring(1, prefix_lower);
+ s.bind_wstring(2, next_prefix);
+ s.bind_int(3, limit);
+ }
+
+ int result;
+ values->clear();
+ while ((result = s.step()) == SQLITE_ROW)
+ values->push_back(s.column_string16(0));
+
+ return result == SQLITE_DONE;
+}
+
void WebDatabase::MigrateOldVersionsAsNeeded() {
// Migrate if necessary.
int current_version = meta_table_.GetVersionNumber();
diff --git a/chrome/browser/webdata/web_database.h b/chrome/browser/webdata/web_database.h
index cff9c88..3b5c660 100644
--- a/chrome/browser/webdata/web_database.h
+++ b/chrome/browser/webdata/web_database.h
@@ -13,6 +13,7 @@
#include "chrome/browser/template_url.h"
#include "chrome/common/sqlite_utils.h"
#include "skia/include/SkBitmap.h"
+#include "webkit/glue/autofill_form.h"
namespace base {
class Time;
@@ -113,6 +114,46 @@ class WebDatabase {
//////////////////////////////////////////////////////////////////////////////
//
+ // Autofill
+ //
+ //////////////////////////////////////////////////////////////////////////////
+
+
+
+ // Records the form elements in |elements| in the database in the autofill
+ // table.
+ bool AddAutofillFormElements(
+ const std::vector<AutofillForm::Element>& elements);
+
+ // Records a single form element in in the database in the autofill table.
+ bool AddAutofillFormElement(const AutofillForm::Element& element);
+
+ // Retrieves a vector of all values which have been recorded in the autofill
+ // table as the value in a form element with name |name| and which start with
+ // |prefix|. The comparison of the prefix is case insensitive.
+ bool GetFormValuesForElementName(const std::wstring& name,
+ const std::wstring& prefix,
+ std::vector<std::wstring>* values,
+ int limit);
+
+ // Gets the pair_id and count entries from name and value specified in
+ // |element|. Sets *count to 0 if there is no such row in the table.
+ bool GetIDAndCountOfFormElement(const AutofillForm::Element& element,
+ int64* pair_id,
+ int* count);
+
+ // Updates the count entry in the row corresponding to |pair_id| to |count|.
+ bool SetCountOfFormElement(int64 pair_id, int count);
+
+ // Adds a new row to the autofill table with name and value given in
+ // |element|. Sets *pair_id to the pair_id of the new row.
+ bool InsertFormElement(const AutofillForm::Element& element, int64* pair_id);
+
+ // Adds a new row to the autofill_dates table.
+ bool InsertPairIDAndDate(int64 pair_id, const base::Time& date_created);
+
+ //////////////////////////////////////////////////////////////////////////////
+ //
// Web Apps
//
//////////////////////////////////////////////////////////////////////////////
@@ -130,6 +171,8 @@ class WebDatabase {
bool InitKeywordsTable();
bool InitLoginsTable();
+ bool InitAutofillTable();
+ bool InitAutofillDatesTable();
bool InitWebAppIconsTable();
bool InitWebAppsTable();