// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef CHROME_BROWSER_WEBDATA_WEB_DATA_SERVICE_H__ #define CHROME_BROWSER_WEBDATA_WEB_DATA_SERVICE_H__ #include "base/basictypes.h" #include "base/lock.h" #include "base/message_loop.h" #include "base/ref_counted.h" #include "base/thread.h" #include "chrome/browser/webdata/web_database.h" #include "chrome/common/scoped_vector.h" #include class GURL; struct PasswordForm; struct IE7PasswordInfo; class ShutdownTask; class TemplateURL; //////////////////////////////////////////////////////////////////////////////// // // WebDataService is a generic data repository for meta data associated with // web pages. All data is retrieved and archived in an asynchronous way. // // All requests return a handle. The handle can be used to cancel the request. // //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // // WebDataService results // //////////////////////////////////////////////////////////////////////////////// // // Result types // typedef enum { BOOL_RESULT = 1, // WDResult KEYWORDS_RESULT, // WDResult INT64_RESULT, // WDResult PASSWORD_RESULT, // WDResult> PASSWORD_IE7_RESULT, // WDResult WEB_APP_IMAGES, // WDResult } WDResultType; // Result from GetWebAppImages. struct WDAppImagesResult { WDAppImagesResult() : has_all_images(false) {} // True if SetWebAppHasAllImages(true) was invoked. bool has_all_images; // The images, may be empty. std::vector images; }; struct WDKeywordsResult { std::vector keywords; // Identifies the ID of the TemplateURL that is the default search. A value of // 0 indicates there is no default search provider. int64 default_search_provider_id; // Version of the builin keywords. A value of 0 indicates a first run. int builtin_keyword_version; }; // // The top level class for a result. // class WDTypedResult { public: virtual ~WDTypedResult() {} // Return the result type. WDResultType GetType() const { return type_; } protected: WDTypedResult(WDResultType type) : type_(type) { } private: WDResultType type_; DISALLOW_EVIL_CONSTRUCTORS(WDTypedResult); }; // A result containing one specific pointer or literal value. template class WDResult : public WDTypedResult { public: WDResult(WDResultType type, T v) : WDTypedResult(type), value_(v) { } virtual ~WDResult() { } // Return a single value result. T GetValue() const { return value_; } private: T value_; DISALLOW_EVIL_CONSTRUCTORS(WDResult); }; template class WDObjectResult : public WDTypedResult { public: explicit WDObjectResult(WDResultType type) : WDTypedResult(type) { } T* GetValue() const { return &value_; } private: // mutable to keep GetValue() const. mutable T value_; DISALLOW_EVIL_CONSTRUCTORS(WDObjectResult); }; class WebDataServiceConsumer; class WebDataService : public base::RefCountedThreadSafe { public: // All requests return an opaque handle of the following type. typedef int Handle; WebDataService(); ~WebDataService(); // Initializes the web data service. Returns false on failure // Takes the path of the profile directory as its argument. bool Init(const std::wstring& profile_path); // Shutdown the web data service. The service can no longer be used after this // call. void Shutdown(); // Returns false if Shutdown() has been called. bool IsRunning(); ////////////////////////////////////////////////////////////////////////////// // // Internal requests // // Every request is processed using a request object. The object contains // both the request parameters and the results. ////////////////////////////////////////////////////////////////////////////// class WebDataRequest { public: WebDataRequest(WebDataService* service, Handle handle, WebDataServiceConsumer* consumer); virtual ~WebDataRequest(); Handle GetHandle() const; WebDataServiceConsumer* GetConsumer() const; bool IsCancelled() const; // This can be invoked from any thread. From this point we assume that // our consumer_ reference is invalid. void Cancel(); // Invoked by the service when this request has been completed. // This will notify the service in whatever thread was used to create this // request. void RequestComplete(); // The result is owned by the request. void SetResult(WDTypedResult* r); const WDTypedResult* GetResult() const; private: scoped_refptr service_; MessageLoop* message_loop_; Handle handle_; bool canceled_; WebDataServiceConsumer* consumer_; WDTypedResult* result_; DISALLOW_EVIL_CONSTRUCTORS(WebDataRequest); }; // // Internally we use instances of the following template to represent // requests. // template class GenericRequest : public WebDataRequest { public: GenericRequest(WebDataService* service, Handle handle, WebDataServiceConsumer* consumer, T arg) : WebDataRequest(service, handle, consumer), arg_(arg) { } virtual ~GenericRequest() { } T GetArgument() { return arg_; } private: T arg_; }; template class GenericRequest2 : public WebDataRequest { public: GenericRequest2(WebDataService* service, Handle handle, WebDataServiceConsumer* consumer, T arg1, U arg2) : WebDataRequest(service, handle, consumer), arg1_(arg1), arg2_(arg2) { } virtual ~GenericRequest2() { } T GetArgument1() { return arg1_; } U GetArgument2() { return arg2_; } private: T arg1_; U arg2_; }; ////////////////////////////////////////////////////////////////////////////// // // Keywords // ////////////////////////////////////////////////////////////////////////////// // As the database processes requests at a later date, all deletion is // done on the background thread. // // Many of the keyword related methods do not return a handle. This is because // the caller (TemplateURLModel) does not need to know when the request is // done. void AddKeyword(const TemplateURL& url); void RemoveKeyword(const TemplateURL& url); void UpdateKeyword(const TemplateURL& url); // Fetches the keywords. // On success, consumer is notified with WDResult. Handle GetKeywords(WebDataServiceConsumer* consumer); // Sets the keywords used for the default search provider. void SetDefaultSearchProvider(const TemplateURL* url); // Sets the version of the builtin keywords. void SetBuiltinKeywordVersion(int version); ////////////////////////////////////////////////////////////////////////////// // // Web Apps // ////////////////////////////////////////////////////////////////////////////// // Sets the image for the specified web app. A web app can have any number of // images, but only one at a particular size. If there was an image for the // web app at the size of the given image it is replaced. void SetWebAppImage(const GURL& app_url, const SkBitmap& image); // Sets whether all the images have been downloaded for the specified web app. void SetWebAppHasAllImages(const GURL& app_url, bool has_all_images); // Removes all images for the specified web app. void RemoveWebApp(const GURL& app_url); // Fetches the images and whether all images have been downloaded for the // specified web app. Handle GetWebAppImages(const GURL& app_url, WebDataServiceConsumer* consumer); ////////////////////////////////////////////////////////////////////////////// // // Password manager // ////////////////////////////////////////////////////////////////////////////// // Updates the remembered password form. void UpdateLogin(const PasswordForm& form); // Adds |form| to the list of remembered password forms. void AddLogin(const PasswordForm& form); // Adds |info| to the list of imported passwords from ie7/ie8. void AddIE7Login(const IE7PasswordInfo& info); // Removes |form| from the list of remembered password forms. void RemoveLogin(const PasswordForm& form); // Removes |info| from the list of imported passwords from ie7/ie8. void RemoveIE7Login(const IE7PasswordInfo& info); // Removes all logins created in the specified daterange void RemoveLoginsCreatedBetween(const Time delete_begin, const Time delete_end); // Removes all logins created on or after the date passed in. void RemoveLoginsCreatedAfter(const Time delete_begin); // Gets a list of password forms that match |form|. // |consumer| will be notified when the request is done. The result is of // type WDResult>. // The result will be null on failure. The |consumer| owns all PasswordForm's. Handle GetLogins(const PasswordForm& form, WebDataServiceConsumer* consumer); // Get the login matching the information in |info|. |consumer| will be // notified when the request is done. The result is of type // WDResult. // If there is no match, the fields of the IE7PasswordInfo will be empty. Handle GetIE7Login(const IE7PasswordInfo& info, WebDataServiceConsumer* consumer); // Gets the complete list of password forms that have not been blacklisted and // are thus auto-fillable. // |consumer| will be notified when the request is done. The result is of // type WDResult>. // The result will be null on failure. The |consumer| owns all PasswordForms. Handle GetAllAutofillableLogins(WebDataServiceConsumer* consumer); // Gets the complete list of password forms. // |consumer| will be notified when the request is done. The result is of // type WDResult>. // The result will be null on failure. The |consumer| owns all PasswordForm's. Handle GetAllLogins(WebDataServiceConsumer* consumer); // Cancel any pending request. You need to call this method if your // WebDataServiceConsumer is about to be deleted. void CancelRequest(Handle h); protected: friend class TemplateURLModelTest; friend class TemplateURLModelTestingProfile; friend class WebDataServiceTest; friend class WebDataRequest; // This is invoked by the unit test; path is the path of the Web Data file. bool WebDataService::InitWithPath(const std::wstring& path); // Invoked by request implementations when a request has been processed. void RequestCompleted(Handle h); // Register the request as a pending request. void RegisterRequest(WebDataRequest* request); ////////////////////////////////////////////////////////////////////////////// // // The following methods are only invoked in the web data service thread. // ////////////////////////////////////////////////////////////////////////////// private: friend class ShutdownTask; typedef GenericRequest2, std::vector> SetKeywordsRequest; // Initialize the database with the provided path. void InitializeDatabase(const std::wstring& path); // Commit any pending transaction and deletes the database. void WebDataService::ShutdownDatabase(); // Commit the current transaction and creates a new one. void Commit(); ////////////////////////////////////////////////////////////////////////////// // // Keywords. // ////////////////////////////////////////////////////////////////////////////// void AddKeywordImpl(GenericRequest* request); void RemoveKeywordImpl(GenericRequest* request); void UpdateKeywordImpl(GenericRequest* request); void GetKeywordsImpl(WebDataRequest* request); void SetDefaultSearchProviderImpl(GenericRequest* r); void SetBuiltinKeywordVersionImpl(GenericRequest* r); ////////////////////////////////////////////////////////////////////////////// // // Password manager. // ////////////////////////////////////////////////////////////////////////////// void AddLoginImpl(GenericRequest* request); void AddIE7LoginImpl(GenericRequest* request); void UpdateLoginImpl(GenericRequest* request); void RemoveLoginImpl(GenericRequest* request); void RemoveIE7LoginImpl(GenericRequest* request); void RemoveLoginsCreatedBetweenImpl(GenericRequest2* request); void GetLoginsImpl(GenericRequest* request); void GetIE7LoginImpl(GenericRequest* request); void GetAllAutofillableLoginsImpl(WebDataRequest* request); void GetAllLoginsImpl(WebDataRequest* request); ////////////////////////////////////////////////////////////////////////////// // // Web Apps. // ////////////////////////////////////////////////////////////////////////////// void SetWebAppImageImpl(GenericRequest2* request); void SetWebAppHasAllImagesImpl(GenericRequest2* request); void RemoveWebAppImpl(GenericRequest* request); void GetWebAppImagesImpl(GenericRequest* request); Thread* thread() { return thread_; } private: // Schedule a task on our worker thread. void ScheduleTask(Task* t); // Schedule a commit if one is not already pending. void ScheduleCommit(); // Return the next request handle. int GetNextRequestHandle(); // Our worker thread. All requests are processed from that thread. Thread* thread_; // Our database. WebDatabase* db_; // Whether we should commit the database. bool should_commit_; // A lock to protect pending requests and next request handle. Lock pending_lock_; // Next handle to be used for requests. Incremented for each use. Handle next_request_handle_; typedef std::map RequestMap; RequestMap pending_requests_; DISALLOW_EVIL_CONSTRUCTORS(WebDataService); }; //////////////////////////////////////////////////////////////////////////////// // // WebDataServiceConsumer. // // All requests to the web data service are asynchronous. When the request has // been performed, the data consumer is notified using the following interface. // //////////////////////////////////////////////////////////////////////////////// class WebDataServiceConsumer { public: // Called when a request is done. h uniquely identifies the request. // result can be NULL, if no result is expected or if the database could // not be opened. The result object is destroyed after this call. virtual void OnWebDataServiceRequestDone(WebDataService::Handle h, const WDTypedResult* result) = 0; }; #endif // CHROME_BROWSER_WEBDATA_WEB_DATA_SERVICE_H__