1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_WEBDATA_WEB_DATA_SERVICE_H__
6#define CHROME_BROWSER_WEBDATA_WEB_DATA_SERVICE_H__
7#pragma once
8
9#include <map>
10#include <string>
11#include <vector>
12
13#include "app/sql/init_status.h"
14#include "base/file_path.h"
15#include "base/memory/ref_counted.h"
16#include "base/synchronization/lock.h"
17#ifdef ANDROID
18// TODO(kristianm): Quick upstream
19#include "base/task.h"
20#include "base/time.h"
21#endif
22#include "chrome/browser/search_engines/template_url_id.h"
23#ifndef ANDROID
24#include "content/browser/browser_thread.h"
25#endif
26#ifdef ANDROID
27#include "third_party/skia/include/core/SkBitmap.h"
28#endif
29
30class AutofillChange;
31class AutofillProfile;
32class CreditCard;
33class GURL;
34#if defined(OS_WIN)
35struct IE7PasswordInfo;
36#endif
37class MessageLoop;
38class SkBitmap;
39class Task;
40class TemplateURL;
41class WebDatabase;
42
43namespace base {
44class Thread;
45}
46
47namespace webkit_glue {
48struct FormField;
49struct PasswordForm;
50}
51
52////////////////////////////////////////////////////////////////////////////////
53//
54// WebDataService is a generic data repository for meta data associated with
55// web pages. All data is retrieved and archived in an asynchronous way.
56//
57// All requests return a handle. The handle can be used to cancel the request.
58//
59////////////////////////////////////////////////////////////////////////////////
60
61
62////////////////////////////////////////////////////////////////////////////////
63//
64// WebDataService results
65//
66////////////////////////////////////////////////////////////////////////////////
67
68//
69// Result types
70//
71typedef enum {
72  BOOL_RESULT = 1,             // WDResult<bool>
73  KEYWORDS_RESULT,             // WDResult<WDKeywordsResult>
74  INT64_RESULT,                // WDResult<int64>
75  PASSWORD_RESULT,             // WDResult<std::vector<PasswordForm*>>
76#if defined(OS_WIN)
77  PASSWORD_IE7_RESULT,         // WDResult<IE7PasswordInfo>
78#endif
79  WEB_APP_IMAGES,              // WDResult<WDAppImagesResult>
80  TOKEN_RESULT,                // WDResult<std::vector<std::string>>
81  AUTOFILL_VALUE_RESULT,       // WDResult<std::vector<string16>>
82  AUTOFILL_CHANGES,            // WDResult<std::vector<AutofillChange>>
83  AUTOFILL_PROFILE_RESULT,     // WDResult<AutofillProfile>
84  AUTOFILL_PROFILES_RESULT,    // WDResult<std::vector<AutofillProfile*>>
85  AUTOFILL_CREDITCARD_RESULT,  // WDResult<CreditCard>
86  AUTOFILL_CREDITCARDS_RESULT  // WDResult<std::vector<CreditCard*>>
87} WDResultType;
88
89typedef std::vector<AutofillChange> AutofillChangeList;
90
91// Result from GetWebAppImages.
92struct WDAppImagesResult {
93  WDAppImagesResult();
94  ~WDAppImagesResult();
95
96  // True if SetWebAppHasAllImages(true) was invoked.
97  bool has_all_images;
98
99  // The images, may be empty.
100  std::vector<SkBitmap> images;
101};
102
103struct WDKeywordsResult {
104  WDKeywordsResult();
105  ~WDKeywordsResult();
106
107  std::vector<TemplateURL*> keywords;
108  // Identifies the ID of the TemplateURL that is the default search. A value of
109  // 0 indicates there is no default search provider.
110  int64 default_search_provider_id;
111  // Version of the built-in keywords. A value of 0 indicates a first run.
112  int builtin_keyword_version;
113};
114
115//
116// The top level class for a result.
117//
118class WDTypedResult {
119 public:
120  virtual ~WDTypedResult() {}
121
122  // Return the result type.
123  WDResultType GetType() const {
124    return type_;
125  }
126
127 protected:
128  explicit WDTypedResult(WDResultType type) : type_(type) {
129  }
130
131 private:
132  WDResultType type_;
133  DISALLOW_COPY_AND_ASSIGN(WDTypedResult);
134};
135
136// A result containing one specific pointer or literal value.
137template <class T> class WDResult : public WDTypedResult {
138 public:
139
140  WDResult(WDResultType type, const T& v) : WDTypedResult(type), value_(v) {
141  }
142
143  virtual ~WDResult() {
144  }
145
146  // Return a single value result.
147  T GetValue() const {
148    return value_;
149  }
150
151 private:
152  T value_;
153
154  DISALLOW_COPY_AND_ASSIGN(WDResult);
155};
156
157template <class T> class WDObjectResult : public WDTypedResult {
158 public:
159  explicit WDObjectResult(WDResultType type) : WDTypedResult(type) {
160  }
161
162  T* GetValue() const {
163    return &value_;
164  }
165
166 private:
167  // mutable to keep GetValue() const.
168  mutable T value_;
169  DISALLOW_COPY_AND_ASSIGN(WDObjectResult);
170};
171
172class WebDataServiceConsumer;
173
174class WebDataService
175    : public base::RefCountedThreadSafe<WebDataService
176#ifndef ANDROID
177                                        , BrowserThread::DeleteOnUIThread
178#endif
179                                       > {
180 public:
181  // All requests return an opaque handle of the following type.
182  typedef int Handle;
183
184  //////////////////////////////////////////////////////////////////////////////
185  //
186  // Internal requests
187  //
188  // Every request is processed using a request object. The object contains
189  // both the request parameters and the results.
190  //////////////////////////////////////////////////////////////////////////////
191  class WebDataRequest {
192   public:
193    WebDataRequest(WebDataService* service,
194                   Handle handle,
195                   WebDataServiceConsumer* consumer);
196
197    virtual ~WebDataRequest();
198
199    Handle GetHandle() const;
200    WebDataServiceConsumer* GetConsumer() const;
201    bool IsCancelled() const;
202
203    // This can be invoked from any thread. From this point we assume that
204    // our consumer_ reference is invalid.
205    void Cancel();
206
207    // Invoked by the service when this request has been completed.
208    // This will notify the service in whatever thread was used to create this
209    // request.
210    void RequestComplete();
211
212    // The result is owned by the request.
213    void SetResult(WDTypedResult* r);
214    const WDTypedResult* GetResult() const;
215
216   private:
217    scoped_refptr<WebDataService> service_;
218    MessageLoop* message_loop_;
219    Handle handle_;
220    bool canceled_;
221    WebDataServiceConsumer* consumer_;
222    WDTypedResult* result_;
223
224    DISALLOW_COPY_AND_ASSIGN(WebDataRequest);
225  };
226
227  //
228  // Internally we use instances of the following template to represent
229  // requests.
230  //
231  template <class T>
232  class GenericRequest : public WebDataRequest {
233   public:
234    GenericRequest(WebDataService* service,
235                   Handle handle,
236                   WebDataServiceConsumer* consumer,
237                   const T& arg)
238        : WebDataRequest(service, handle, consumer),
239          arg_(arg) {
240    }
241
242    virtual ~GenericRequest() {
243    }
244
245    T GetArgument() {
246      return arg_;
247    }
248
249   private:
250    T arg_;
251  };
252
253  template <class T, class U>
254  class GenericRequest2 : public WebDataRequest {
255   public:
256    GenericRequest2(WebDataService* service,
257                    Handle handle,
258                    WebDataServiceConsumer* consumer,
259                    const T& arg1,
260                    const U& arg2)
261        : WebDataRequest(service, handle, consumer),
262          arg1_(arg1),
263          arg2_(arg2) {
264    }
265
266    virtual ~GenericRequest2() { }
267
268    T GetArgument1() {
269      return arg1_;
270    }
271
272    U GetArgument2() {
273      return arg2_;
274    }
275
276   private:
277    T arg1_;
278    U arg2_;
279  };
280
281  WebDataService();
282
283  // Initializes the web data service. Returns false on failure
284  // Takes the path of the profile directory as its argument.
285  bool Init(const FilePath& profile_path);
286
287  // Shutdown the web data service. The service can no longer be used after this
288  // call.
289  void Shutdown();
290
291  // Returns false if Shutdown() has been called.
292  bool IsRunning() const;
293
294  // Unloads the database without actually shutting down the service.  This can
295  // be used to temporarily reduce the browser process' memory footprint.
296  void UnloadDatabase();
297
298  // Cancel any pending request. You need to call this method if your
299  // WebDataServiceConsumer is about to be deleted.
300  void CancelRequest(Handle h);
301
302  virtual bool IsDatabaseLoaded();
303  virtual WebDatabase* GetDatabase();
304
305  //////////////////////////////////////////////////////////////////////////////
306  //
307  // Keywords
308  //
309  //////////////////////////////////////////////////////////////////////////////
310
311  // As the database processes requests at a later date, all deletion is
312  // done on the background thread.
313  //
314  // Many of the keyword related methods do not return a handle. This is because
315  // the caller (TemplateURLModel) does not need to know when the request is
316  // done.
317  void AddKeyword(const TemplateURL& url);
318
319  void RemoveKeyword(const TemplateURL& url);
320
321  void UpdateKeyword(const TemplateURL& url);
322
323  // Fetches the keywords.
324  // On success, consumer is notified with WDResult<std::vector<TemplateURL*>.
325  Handle GetKeywords(WebDataServiceConsumer* consumer);
326
327  // Sets the keywords used for the default search provider.
328  void SetDefaultSearchProvider(const TemplateURL* url);
329
330  // Sets the version of the builtin keywords.
331  void SetBuiltinKeywordVersion(int version);
332
333  //////////////////////////////////////////////////////////////////////////////
334  //
335  // Web Apps
336  //
337  //////////////////////////////////////////////////////////////////////////////
338
339  // Sets the image for the specified web app. A web app can have any number of
340  // images, but only one at a particular size. If there was an image for the
341  // web app at the size of the given image it is replaced.
342  void SetWebAppImage(const GURL& app_url, const SkBitmap& image);
343
344  // Sets whether all the images have been downloaded for the specified web app.
345  void SetWebAppHasAllImages(const GURL& app_url, bool has_all_images);
346
347  // Removes all images for the specified web app.
348  void RemoveWebApp(const GURL& app_url);
349
350  // Fetches the images and whether all images have been downloaded for the
351  // specified web app.
352  Handle GetWebAppImages(const GURL& app_url, WebDataServiceConsumer* consumer);
353
354  //////////////////////////////////////////////////////////////////////////////
355  //
356  // Token Service
357  //
358  //////////////////////////////////////////////////////////////////////////////
359
360  // Set a token to use for a specified service.
361  void SetTokenForService(const std::string& service,
362                          const std::string& token);
363
364  // Remove all tokens stored in the web database.
365  void RemoveAllTokens();
366
367  // Null on failure. Success is WDResult<std::vector<std::string> >
368  Handle GetAllTokens(WebDataServiceConsumer* consumer);
369
370  //////////////////////////////////////////////////////////////////////////////
371  //
372  // Password manager
373  // NOTE: These methods are all deprecated; new clients should use
374  // PasswordStore. These are only still here because Windows is (temporarily)
375  // still using them for its PasswordStore implementation.
376  //
377  //////////////////////////////////////////////////////////////////////////////
378
379  // Adds |form| to the list of remembered password forms.
380  void AddLogin(const webkit_glue::PasswordForm& form);
381
382  // Updates the remembered password form.
383  void UpdateLogin(const webkit_glue::PasswordForm& form);
384
385  // Removes |form| from the list of remembered password forms.
386  void RemoveLogin(const webkit_glue::PasswordForm& form);
387
388  // Removes all logins created in the specified daterange
389  void RemoveLoginsCreatedBetween(const base::Time& delete_begin,
390                                  const base::Time& delete_end);
391
392  // Removes all logins created on or after the date passed in.
393  void RemoveLoginsCreatedAfter(const base::Time& delete_begin);
394
395  // Gets a list of password forms that match |form|.
396  // |consumer| will be notified when the request is done. The result is of
397  // type WDResult<std::vector<PasswordForm*>>.
398  // The result will be null on failure. The |consumer| owns all PasswordForm's.
399  Handle GetLogins(const webkit_glue::PasswordForm& form,
400                   WebDataServiceConsumer* consumer);
401
402  // Gets the complete list of password forms that have not been blacklisted and
403  // are thus auto-fillable.
404  // |consumer| will be notified when the request is done. The result is of
405  // type WDResult<std::vector<PasswordForm*>>.
406  // The result will be null on failure.  The |consumer| owns all PasswordForms.
407  Handle GetAutofillableLogins(WebDataServiceConsumer* consumer);
408
409  // Gets the complete list of password forms that have been blacklisted.
410  // |consumer| will be notified when the request is done. The result is of
411  // type WDResult<std::vector<PasswordForm*>>.
412  // The result will be null on failure. The |consumer| owns all PasswordForm's.
413  Handle GetBlacklistLogins(WebDataServiceConsumer* consumer);
414
415#if defined(OS_WIN)
416  // Adds |info| to the list of imported passwords from ie7/ie8.
417  void AddIE7Login(const IE7PasswordInfo& info);
418
419  // Removes |info| from the list of imported passwords from ie7/ie8.
420  void RemoveIE7Login(const IE7PasswordInfo& info);
421
422  // Get the login matching the information in |info|. |consumer| will be
423  // notified when the request is done. The result is of type
424  // WDResult<IE7PasswordInfo>.
425  // If there is no match, the fields of the IE7PasswordInfo will be empty.
426  Handle GetIE7Login(const IE7PasswordInfo& info,
427                     WebDataServiceConsumer* consumer);
428#endif  // defined(OS_WIN)
429
430  //////////////////////////////////////////////////////////////////////////////
431  //
432  // Autofill.
433  //
434  //////////////////////////////////////////////////////////////////////////////
435
436  // Schedules a task to add form fields to the web database.
437  virtual void AddFormFields(const std::vector<webkit_glue::FormField>& fields);
438
439  // Initiates the request for a vector of values which have been entered in
440  // form input fields named |name|.  The method OnWebDataServiceRequestDone of
441  // |consumer| gets called back when the request is finished, with the vector
442  // included in the argument |result|.
443  Handle GetFormValuesForElementName(const string16& name,
444                                     const string16& prefix,
445                                     int limit,
446                                     WebDataServiceConsumer* consumer);
447
448  // Removes form elements recorded for Autocomplete from the database.
449  void RemoveFormElementsAddedBetween(const base::Time& delete_begin,
450                                      const base::Time& delete_end);
451  void RemoveFormValueForElementName(const string16& name,
452                                     const string16& value);
453
454  // Schedules a task to add an Autofill profile to the web database.
455  void AddAutofillProfile(const AutofillProfile& profile);
456
457  // Schedules a task to update an Autofill profile in the web database.
458  void UpdateAutofillProfile(const AutofillProfile& profile);
459
460  // Schedules a task to remove an Autofill profile from the web database.
461  // |guid| is the identifer of the profile to remove.
462  void RemoveAutofillProfile(const std::string& guid);
463
464  // Initiates the request for all Autofill profiles.  The method
465  // OnWebDataServiceRequestDone of |consumer| gets called when the request is
466  // finished, with the profiles included in the argument |result|.  The
467  // consumer owns the profiles.
468  Handle GetAutofillProfiles(WebDataServiceConsumer* consumer);
469
470  // Remove "trashed" profile guids from the web database and optionally send
471  // notifications to tell Sync that the items have been removed.
472  void EmptyMigrationTrash(bool notify_sync);
473
474  // Schedules a task to add credit card to the web database.
475  void AddCreditCard(const CreditCard& credit_card);
476
477  // Schedules a task to update credit card in the web database.
478  void UpdateCreditCard(const CreditCard& credit_card);
479
480  // Schedules a task to remove a credit card from the web database.
481  // |guid| is identifer of the credit card to remove.
482  void RemoveCreditCard(const std::string& guid);
483
484  // Initiates the request for all credit cards.  The method
485  // OnWebDataServiceRequestDone of |consumer| gets called when the request is
486  // finished, with the credit cards included in the argument |result|.  The
487  // consumer owns the credit cards.
488  Handle GetCreditCards(WebDataServiceConsumer* consumer);
489
490  // Removes Autofill records from the database.
491  void RemoveAutofillProfilesAndCreditCardsModifiedBetween(
492      const base::Time& delete_begin,
493      const base::Time& delete_end);
494
495  // Testing
496#ifdef UNIT_TEST
497  void set_failed_init(bool value) { failed_init_ = value; }
498#endif
499
500 protected:
501  friend class TemplateURLModelTest;
502  friend class TemplateURLModelTestingProfile;
503  friend class WebDataServiceTest;
504  friend class WebDataRequest;
505
506  virtual ~WebDataService();
507
508  // This is invoked by the unit test; path is the path of the Web Data file.
509  bool InitWithPath(const FilePath& path);
510
511  // Invoked by request implementations when a request has been processed.
512  void RequestCompleted(Handle h);
513
514  // Register the request as a pending request.
515  void RegisterRequest(WebDataRequest* request);
516
517  //////////////////////////////////////////////////////////////////////////////
518  //
519  // The following methods are only invoked in the web data service thread.
520  //
521  //////////////////////////////////////////////////////////////////////////////
522 private:
523#ifndef ANDROID
524  friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
525#endif
526  friend class DeleteTask<WebDataService>;
527  friend class ShutdownTask;
528
529  typedef GenericRequest2<std::vector<const TemplateURL*>,
530                          std::vector<TemplateURL*> > SetKeywordsRequest;
531
532  // Invoked on the main thread if initializing the db fails.
533  void DBInitFailed(sql::InitStatus init_status);
534
535  // Initialize the database, if it hasn't already been initialized.
536  void InitializeDatabaseIfNecessary();
537
538  // The notification method.
539  void NotifyDatabaseLoadedOnUIThread();
540
541  // Commit any pending transaction and deletes the database.
542  void ShutdownDatabase();
543
544  // Commit the current transaction and creates a new one.
545  void Commit();
546
547  // Schedule a task on our worker thread.
548  void ScheduleTask(Task* t);
549
550  // Schedule a commit if one is not already pending.
551  void ScheduleCommit();
552
553  // Return the next request handle.
554  int GetNextRequestHandle();
555
556  //////////////////////////////////////////////////////////////////////////////
557  //
558  // Keywords.
559  //
560  //////////////////////////////////////////////////////////////////////////////
561  void AddKeywordImpl(GenericRequest<TemplateURL>* request);
562  void RemoveKeywordImpl(GenericRequest<TemplateURLID>* request);
563  void UpdateKeywordImpl(GenericRequest<TemplateURL>* request);
564  void GetKeywordsImpl(WebDataRequest* request);
565  void SetDefaultSearchProviderImpl(GenericRequest<TemplateURLID>* r);
566  void SetBuiltinKeywordVersionImpl(GenericRequest<int>* r);
567
568  //////////////////////////////////////////////////////////////////////////////
569  //
570  // Web Apps.
571  //
572  //////////////////////////////////////////////////////////////////////////////
573  void SetWebAppImageImpl(GenericRequest2<GURL, SkBitmap>* request);
574  void SetWebAppHasAllImagesImpl(GenericRequest2<GURL, bool>* request);
575  void RemoveWebAppImpl(GenericRequest<GURL>* request);
576  void GetWebAppImagesImpl(GenericRequest<GURL>* request);
577
578  //////////////////////////////////////////////////////////////////////////////
579  //
580  // Token Service.
581  //
582  //////////////////////////////////////////////////////////////////////////////
583
584  void RemoveAllTokensImpl(GenericRequest<std::string>* request);
585  void SetTokenForServiceImpl(
586    GenericRequest2<std::string, std::string>* request);
587  void GetAllTokensImpl(GenericRequest<std::string>* request);
588
589  //////////////////////////////////////////////////////////////////////////////
590  //
591  // Password manager.
592  //
593  //////////////////////////////////////////////////////////////////////////////
594  void AddLoginImpl(GenericRequest<webkit_glue::PasswordForm>* request);
595  void UpdateLoginImpl(GenericRequest<webkit_glue::PasswordForm>* request);
596  void RemoveLoginImpl(GenericRequest<webkit_glue::PasswordForm>* request);
597  void RemoveLoginsCreatedBetweenImpl(
598      GenericRequest2<base::Time, base::Time>* request);
599  void GetLoginsImpl(GenericRequest<webkit_glue::PasswordForm>* request);
600  void GetAutofillableLoginsImpl(WebDataRequest* request);
601  void GetBlacklistLoginsImpl(WebDataRequest* request);
602#if defined(OS_WIN)
603  void AddIE7LoginImpl(GenericRequest<IE7PasswordInfo>* request);
604  void RemoveIE7LoginImpl(GenericRequest<IE7PasswordInfo>* request);
605  void GetIE7LoginImpl(GenericRequest<IE7PasswordInfo>* request);
606#endif  // defined(OS_WIN)
607
608  //////////////////////////////////////////////////////////////////////////////
609  //
610  // Autofill.
611  //
612  //////////////////////////////////////////////////////////////////////////////
613  void AddFormElementsImpl(
614      GenericRequest<std::vector<webkit_glue::FormField> >* request);
615  void GetFormValuesForElementNameImpl(WebDataRequest* request,
616      const string16& name, const string16& prefix, int limit);
617  void RemoveFormElementsAddedBetweenImpl(
618      GenericRequest2<base::Time, base::Time>* request);
619  void RemoveFormValueForElementNameImpl(
620      GenericRequest2<string16, string16>* request);
621  void AddAutofillProfileImpl(GenericRequest<AutofillProfile>* request);
622  void UpdateAutofillProfileImpl(GenericRequest<AutofillProfile>* request);
623  void RemoveAutofillProfileImpl(GenericRequest<std::string>* request);
624  void GetAutofillProfilesImpl(WebDataRequest* request);
625  void EmptyMigrationTrashImpl(GenericRequest<bool>* request);
626  void AddCreditCardImpl(GenericRequest<CreditCard>* request);
627  void UpdateCreditCardImpl(GenericRequest<CreditCard>* request);
628  void RemoveCreditCardImpl(GenericRequest<std::string>* request);
629  void GetCreditCardsImpl(WebDataRequest* request);
630  void RemoveAutofillProfilesAndCreditCardsModifiedBetweenImpl(
631      GenericRequest2<base::Time, base::Time>* request);
632
633  // True once initialization has started.
634  bool is_running_;
635
636  // The path with which to initialize the database.
637  FilePath path_;
638
639  // Our database.
640  WebDatabase* db_;
641
642  // Whether the database failed to initialize.  We use this to avoid
643  // continually trying to reinit.
644  bool failed_init_;
645
646  // Whether we should commit the database.
647  bool should_commit_;
648
649  // A lock to protect pending requests and next request handle.
650  base::Lock pending_lock_;
651
652  // Next handle to be used for requests. Incremented for each use.
653  Handle next_request_handle_;
654
655  typedef std::map<Handle, WebDataRequest*> RequestMap;
656  RequestMap pending_requests_;
657
658  // MessageLoop the WebDataService is created on.
659  MessageLoop* main_loop_;
660
661  DISALLOW_COPY_AND_ASSIGN(WebDataService);
662};
663
664////////////////////////////////////////////////////////////////////////////////
665//
666// WebDataServiceConsumer.
667//
668// All requests to the web data service are asynchronous. When the request has
669// been performed, the data consumer is notified using the following interface.
670//
671////////////////////////////////////////////////////////////////////////////////
672
673class WebDataServiceConsumer {
674 public:
675
676  // Called when a request is done. h uniquely identifies the request.
677  // result can be NULL, if no result is expected or if the database could
678  // not be opened. The result object is destroyed after this call.
679  virtual void OnWebDataServiceRequestDone(WebDataService::Handle h,
680                                           const WDTypedResult* result) = 0;
681
682 protected:
683  virtual ~WebDataServiceConsumer() {}
684};
685
686#endif  // CHROME_BROWSER_WEBDATA_WEB_DATA_SERVICE_H__
687