• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
30 class AutofillChange;
31 class AutofillProfile;
32 class CreditCard;
33 class GURL;
34 #if defined(OS_WIN)
35 struct IE7PasswordInfo;
36 #endif
37 class MessageLoop;
38 class SkBitmap;
39 class Task;
40 class TemplateURL;
41 class WebDatabase;
42 
43 namespace base {
44 class Thread;
45 }
46 
47 namespace webkit_glue {
48 struct FormField;
49 struct 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 //
71 typedef 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 
89 typedef std::vector<AutofillChange> AutofillChangeList;
90 
91 // Result from GetWebAppImages.
92 struct 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 
103 struct 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 //
118 class WDTypedResult {
119  public:
~WDTypedResult()120   virtual ~WDTypedResult() {}
121 
122   // Return the result type.
GetType()123   WDResultType GetType() const {
124     return type_;
125   }
126 
127  protected:
WDTypedResult(WDResultType type)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.
137 template <class T> class WDResult : public WDTypedResult {
138  public:
139 
WDResult(WDResultType type,const T & v)140   WDResult(WDResultType type, const T& v) : WDTypedResult(type), value_(v) {
141   }
142 
~WDResult()143   virtual ~WDResult() {
144   }
145 
146   // Return a single value result.
GetValue()147   T GetValue() const {
148     return value_;
149   }
150 
151  private:
152   T value_;
153 
154   DISALLOW_COPY_AND_ASSIGN(WDResult);
155 };
156 
157 template <class T> class WDObjectResult : public WDTypedResult {
158  public:
WDObjectResult(WDResultType type)159   explicit WDObjectResult(WDResultType type) : WDTypedResult(type) {
160   }
161 
GetValue()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 
172 class WebDataServiceConsumer;
173 
174 class 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:
GenericRequest(WebDataService * service,Handle handle,WebDataServiceConsumer * consumer,const T & arg)234     GenericRequest(WebDataService* service,
235                    Handle handle,
236                    WebDataServiceConsumer* consumer,
237                    const T& arg)
238         : WebDataRequest(service, handle, consumer),
239           arg_(arg) {
240     }
241 
~GenericRequest()242     virtual ~GenericRequest() {
243     }
244 
GetArgument()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:
GenericRequest2(WebDataService * service,Handle handle,WebDataServiceConsumer * consumer,const T & arg1,const U & arg2)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 
~GenericRequest2()266     virtual ~GenericRequest2() { }
267 
GetArgument1()268     T GetArgument1() {
269       return arg1_;
270     }
271 
GetArgument2()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
set_failed_init(bool value)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 
673 class 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