Home | History | Annotate | Download | only in icon
      1 /*
      2  * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
      3  * Copyright (C) 2007 Justin Haygood (jhaygood (at) reaktix.com)
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #ifndef IconDatabase_h
     28 #define IconDatabase_h
     29 
     30 #include "IconDatabaseBase.h"
     31 #include "Timer.h"
     32 #include <wtf/HashMap.h>
     33 #include <wtf/HashSet.h>
     34 #include <wtf/Noncopyable.h>
     35 #include <wtf/OwnPtr.h>
     36 #include <wtf/PassOwnPtr.h>
     37 #include <wtf/text/StringHash.h>
     38 #include <wtf/text/WTFString.h>
     39 
     40 #if ENABLE(ICONDATABASE)
     41 #include "SQLiteDatabase.h"
     42 #include <wtf/Threading.h>
     43 #endif // ENABLE(ICONDATABASE)
     44 
     45 namespace WebCore {
     46 
     47 class DocumentLoader;
     48 class Image;
     49 class IntSize;
     50 class IconDatabaseClient;
     51 class IconRecord;
     52 class IconSnapshot;
     53 class KURL;
     54 class PageURLRecord;
     55 class PageURLSnapshot;
     56 class SharedBuffer;
     57 
     58 #if ENABLE(ICONDATABASE)
     59 class SQLTransaction;
     60 #endif
     61 
     62 #if !ENABLE(ICONDATABASE)
     63 // For builds with IconDatabase disabled, they'll just use a default derivation of IconDatabaseBase. Which does nothing.
     64 class IconDatabase : public IconDatabaseBase {
     65 public:
     66     static void delayDatabaseCleanup() { }
     67     static String defaultDatabaseFilename() { return "WebpageIcons.db"; }
     68 };
     69 #else
     70 
     71 class IconDatabase : public IconDatabaseBase {
     72     WTF_MAKE_FAST_ALLOCATED;
     73 
     74 // *** Main Thread Only ***
     75 public:
     76     static PassOwnPtr<IconDatabase> create() { return new IconDatabase; }
     77     ~IconDatabase();
     78 
     79     virtual void setClient(IconDatabaseClient*);
     80 
     81     virtual bool open(const String& directory, const String& filename);
     82     virtual void close();
     83 
     84     virtual void removeAllIcons();
     85 
     86     void readIconForPageURLFromDisk(const String&);
     87 
     88     virtual Image* defaultIcon(const IntSize&);
     89 
     90     virtual void retainIconForPageURL(const String&);
     91     virtual void releaseIconForPageURL(const String&);
     92     virtual void setIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String&);
     93     virtual void setIconURLForPageURL(const String& iconURL, const String& pageURL);
     94 
     95     virtual Image* synchronousIconForPageURL(const String&, const IntSize&);
     96     virtual String synchronousIconURLForPageURL(const String&);
     97     virtual bool synchronousIconDataKnownForIconURL(const String&);
     98     virtual IconLoadDecision synchronousLoadDecisionForIconURL(const String&, DocumentLoader*);
     99 
    100     virtual void setEnabled(bool);
    101     virtual bool isEnabled() const;
    102 
    103     virtual void setPrivateBrowsingEnabled(bool flag);
    104     bool isPrivateBrowsingEnabled() const;
    105 
    106     static void delayDatabaseCleanup();
    107     static void allowDatabaseCleanup();
    108     static void checkIntegrityBeforeOpening();
    109 
    110     // Support for WebCoreStatistics in WebKit
    111     virtual size_t pageURLMappingCount();
    112     virtual size_t retainedPageURLCount();
    113     virtual size_t iconRecordCount();
    114     virtual size_t iconRecordCountWithData();
    115 
    116 private:
    117     IconDatabase();
    118     friend IconDatabaseBase& iconDatabase();
    119 
    120     static void notifyPendingLoadDecisionsOnMainThread(void*);
    121     void notifyPendingLoadDecisions();
    122 
    123     void wakeSyncThread();
    124     void scheduleOrDeferSyncTimer();
    125     void syncTimerFired(Timer<IconDatabase>*);
    126 
    127     Timer<IconDatabase> m_syncTimer;
    128     ThreadIdentifier m_syncThread;
    129     bool m_syncThreadRunning;
    130 
    131     HashSet<RefPtr<DocumentLoader> > m_loadersPendingDecision;
    132 
    133     RefPtr<IconRecord> m_defaultIconRecord;
    134 
    135 // *** Any Thread ***
    136 public:
    137     virtual bool isOpen() const;
    138     virtual String databasePath() const;
    139     static String defaultDatabaseFilename();
    140 
    141 private:
    142     PassRefPtr<IconRecord> getOrCreateIconRecord(const String& iconURL);
    143     PageURLRecord* getOrCreatePageURLRecord(const String& pageURL);
    144 
    145     bool m_isEnabled;
    146     bool m_privateBrowsingEnabled;
    147 
    148     mutable Mutex m_syncLock;
    149     ThreadCondition m_syncCondition;
    150     String m_databaseDirectory;
    151     // Holding m_syncLock is required when accessing m_completeDatabasePath
    152     String m_completeDatabasePath;
    153 
    154     bool m_threadTerminationRequested;
    155     bool m_removeIconsRequested;
    156     bool m_iconURLImportComplete;
    157     bool m_disabledSuddenTerminationForSyncThread;
    158 
    159     Mutex m_urlAndIconLock;
    160     // Holding m_urlAndIconLock is required when accessing any of the following data structures or the objects they contain
    161     HashMap<String, IconRecord*> m_iconURLToRecordMap;
    162     HashMap<String, PageURLRecord*> m_pageURLToRecordMap;
    163     HashSet<String> m_retainedPageURLs;
    164 
    165     Mutex m_pendingSyncLock;
    166     // Holding m_pendingSyncLock is required when accessing any of the following data structures
    167     HashMap<String, PageURLSnapshot> m_pageURLsPendingSync;
    168     HashMap<String, IconSnapshot> m_iconsPendingSync;
    169 
    170     Mutex m_pendingReadingLock;
    171     // Holding m_pendingSyncLock is required when accessing any of the following data structures - when dealing with IconRecord*s, holding m_urlAndIconLock is also required
    172     HashSet<String> m_pageURLsPendingImport;
    173     HashSet<String> m_pageURLsInterestedInIcons;
    174     HashSet<IconRecord*> m_iconsPendingReading;
    175 
    176 // *** Sync Thread Only ***
    177 public:
    178     // Should be used only on the sync thread and only by the Safari 2 Icons import procedure
    179     virtual void importIconURLForPageURL(const String& iconURL, const String& pageURL);
    180     virtual void importIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String& iconURL);
    181 
    182     virtual bool shouldStopThreadActivity() const;
    183 
    184 private:
    185     static void* iconDatabaseSyncThreadStart(void *);
    186     void* iconDatabaseSyncThread();
    187 
    188     // The following block of methods are called exclusively by the sync thread to manage i/o to and from the database
    189     // Each method should periodically monitor m_threadTerminationRequested when it makes sense to return early on shutdown
    190     void performOpenInitialization();
    191     bool checkIntegrity();
    192     void performURLImport();
    193     void* syncThreadMainLoop();
    194     bool readFromDatabase();
    195     bool writeToDatabase();
    196     void pruneUnretainedIcons();
    197     void checkForDanglingPageURLs(bool pruneIfFound);
    198     void removeAllIconsOnThread();
    199     void deleteAllPreparedStatements();
    200     void* cleanupSyncThread();
    201 
    202     // Record (on disk) whether or not Safari 2-style icons were imported (once per dataabse)
    203     bool imported();
    204     void setImported(bool);
    205 
    206     bool wasExcludedFromBackup();
    207     void setWasExcludedFromBackup();
    208 
    209     bool m_initialPruningComplete;
    210 
    211     void setIconURLForPageURLInSQLDatabase(const String&, const String&);
    212     void setIconIDForPageURLInSQLDatabase(int64_t, const String&);
    213     void removePageURLFromSQLDatabase(const String& pageURL);
    214     int64_t getIconIDForIconURLFromSQLDatabase(const String& iconURL);
    215     int64_t addIconURLToSQLDatabase(const String&);
    216     PassRefPtr<SharedBuffer> getImageDataForIconURLFromSQLDatabase(const String& iconURL);
    217     void removeIconFromSQLDatabase(const String& iconURL);
    218     void writeIconSnapshotToSQLDatabase(const IconSnapshot&);
    219 
    220     // Methods to dispatch client callbacks on the main thread
    221     void dispatchDidImportIconURLForPageURLOnMainThread(const String&);
    222     void dispatchDidImportIconDataForPageURLOnMainThread(const String&);
    223     void dispatchDidRemoveAllIconsOnMainThread();
    224     void dispatchDidFinishURLImportOnMainThread();
    225 
    226     // The client is set by the main thread before the thread starts, and from then on is only used by the sync thread
    227     IconDatabaseClient* m_client;
    228 
    229     SQLiteDatabase m_syncDB;
    230 
    231     // Track whether the "Safari 2" import is complete and/or set in the database
    232     bool m_imported;
    233     bool m_isImportedSet;
    234 
    235     OwnPtr<SQLiteStatement> m_setIconIDForPageURLStatement;
    236     OwnPtr<SQLiteStatement> m_removePageURLStatement;
    237     OwnPtr<SQLiteStatement> m_getIconIDForIconURLStatement;
    238     OwnPtr<SQLiteStatement> m_getImageDataForIconURLStatement;
    239     OwnPtr<SQLiteStatement> m_addIconToIconInfoStatement;
    240     OwnPtr<SQLiteStatement> m_addIconToIconDataStatement;
    241     OwnPtr<SQLiteStatement> m_getImageDataStatement;
    242     OwnPtr<SQLiteStatement> m_deletePageURLsForIconURLStatement;
    243     OwnPtr<SQLiteStatement> m_deleteIconFromIconInfoStatement;
    244     OwnPtr<SQLiteStatement> m_deleteIconFromIconDataStatement;
    245     OwnPtr<SQLiteStatement> m_updateIconInfoStatement;
    246     OwnPtr<SQLiteStatement> m_updateIconDataStatement;
    247     OwnPtr<SQLiteStatement> m_setIconInfoStatement;
    248     OwnPtr<SQLiteStatement> m_setIconDataStatement;
    249 };
    250 
    251 #endif // !ENABLE(ICONDATABASE)
    252 
    253 } // namespace WebCore
    254 
    255 #endif // IconDatabase_h
    256