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 "StringHash.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 
     37 #if ENABLE(ICONDATABASE)
     38 #include "SQLiteDatabase.h"
     39 #include <wtf/Threading.h>
     40 #endif
     41 
     42 namespace WebCore {
     43 
     44 class DocumentLoader;
     45 class Image;
     46 class IntSize;
     47 class IconDatabaseClient;
     48 class IconRecord;
     49 class IconSnapshot;
     50 class KURL;
     51 class PageURLRecord;
     52 class PageURLSnapshot;
     53 class SharedBuffer;
     54 
     55 #if ENABLE(ICONDATABASE)
     56 class SQLTransaction;
     57 #endif
     58 
     59 enum IconLoadDecision {
     60     IconLoadYes,
     61     IconLoadNo,
     62     IconLoadUnknown
     63 };
     64 
     65 class IconDatabase : public Noncopyable {
     66 
     67 // *** Main Thread Only ***
     68 public:
     69     void setClient(IconDatabaseClient*);
     70 
     71     bool open(const String& path);
     72     void close();
     73 
     74     void removeAllIcons();
     75 
     76     Image* iconForPageURL(const String&, const IntSize&);
     77     void readIconForPageURLFromDisk(const String&);
     78     String iconURLForPageURL(const String&);
     79     Image* defaultIcon(const IntSize&);
     80 
     81     void retainIconForPageURL(const String&);
     82     void releaseIconForPageURL(const String&);
     83 
     84     void setIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String&);
     85     void setIconURLForPageURL(const String& iconURL, const String& pageURL);
     86 
     87     IconLoadDecision loadDecisionForIconURL(const String&, DocumentLoader*);
     88     bool iconDataKnownForIconURL(const String&);
     89 
     90     void setEnabled(bool enabled);
     91     bool isEnabled() const;
     92 
     93     void setPrivateBrowsingEnabled(bool flag);
     94     bool isPrivateBrowsingEnabled() const;
     95 
     96     static void delayDatabaseCleanup();
     97     static void allowDatabaseCleanup();
     98     static void checkIntegrityBeforeOpening();
     99 
    100     // Support for WebCoreStatistics in WebKit
    101     size_t pageURLMappingCount();
    102     size_t retainedPageURLCount();
    103     size_t iconRecordCount();
    104     size_t iconRecordCountWithData();
    105 
    106 private:
    107     IconDatabase();
    108     ~IconDatabase();
    109     friend IconDatabase* iconDatabase();
    110 
    111 #if ENABLE(ICONDATABASE)
    112     static void notifyPendingLoadDecisionsOnMainThread(void*);
    113     void notifyPendingLoadDecisions();
    114 
    115     void wakeSyncThread();
    116     void scheduleOrDeferSyncTimer();
    117     void syncTimerFired(Timer<IconDatabase>*);
    118 
    119     Timer<IconDatabase> m_syncTimer;
    120     ThreadIdentifier m_syncThread;
    121     bool m_syncThreadRunning;
    122 
    123     HashSet<RefPtr<DocumentLoader> > m_loadersPendingDecision;
    124 
    125     RefPtr<IconRecord> m_defaultIconRecord;
    126 #endif // ENABLE(ICONDATABASE)
    127 
    128 // *** Any Thread ***
    129 public:
    130     bool isOpen() const;
    131     String databasePath() const;
    132     static String defaultDatabaseFilename();
    133 
    134 #if ENABLE(ICONDATABASE)
    135 private:
    136     PassRefPtr<IconRecord> getOrCreateIconRecord(const String& iconURL);
    137     PageURLRecord* getOrCreatePageURLRecord(const String& pageURL);
    138 
    139     bool m_isEnabled;
    140     bool m_privateBrowsingEnabled;
    141 
    142     mutable Mutex m_syncLock;
    143     ThreadCondition m_syncCondition;
    144     String m_databaseDirectory;
    145     // Holding m_syncLock is required when accessing m_completeDatabasePath
    146     String m_completeDatabasePath;
    147 
    148     bool m_threadTerminationRequested;
    149     bool m_removeIconsRequested;
    150     bool m_iconURLImportComplete;
    151 
    152     Mutex m_urlAndIconLock;
    153     // Holding m_urlAndIconLock is required when accessing any of the following data structures or the objects they contain
    154     HashMap<String, IconRecord*> m_iconURLToRecordMap;
    155     HashMap<String, PageURLRecord*> m_pageURLToRecordMap;
    156     HashSet<String> m_retainedPageURLs;
    157 
    158     Mutex m_pendingSyncLock;
    159     // Holding m_pendingSyncLock is required when accessing any of the following data structures
    160     HashMap<String, PageURLSnapshot> m_pageURLsPendingSync;
    161     HashMap<String, IconSnapshot> m_iconsPendingSync;
    162 
    163     Mutex m_pendingReadingLock;
    164     // Holding m_pendingSyncLock is required when accessing any of the following data structures - when dealing with IconRecord*s, holding m_urlAndIconLock is also required
    165     HashSet<String> m_pageURLsPendingImport;
    166     HashSet<String> m_pageURLsInterestedInIcons;
    167     HashSet<IconRecord*> m_iconsPendingReading;
    168 #endif // ENABLE(ICONDATABASE)
    169 
    170 // *** Sync Thread Only ***
    171 public:
    172     // Should be used only on the sync thread and only by the Safari 2 Icons import procedure
    173     void importIconURLForPageURL(const String& iconURL, const String& pageURL);
    174     void importIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String& iconURL);
    175 
    176     bool shouldStopThreadActivity() const;
    177 
    178 #if ENABLE(ICONDATABASE)
    179 private:
    180     static void* iconDatabaseSyncThreadStart(void *);
    181     void* iconDatabaseSyncThread();
    182 
    183     // The following block of methods are called exclusively by the sync thread to manage i/o to and from the database
    184     // Each method should periodically monitor m_threadTerminationRequested when it makes sense to return early on shutdown
    185     void performOpenInitialization();
    186     bool checkIntegrity();
    187     void performURLImport();
    188     void* syncThreadMainLoop();
    189     bool readFromDatabase();
    190     bool writeToDatabase();
    191     void pruneUnretainedIcons();
    192     void checkForDanglingPageURLs(bool pruneIfFound);
    193     void removeAllIconsOnThread();
    194     void deleteAllPreparedStatements();
    195     void* cleanupSyncThread();
    196 
    197     // Record (on disk) whether or not Safari 2-style icons were imported (once per dataabse)
    198     bool imported();
    199     void setImported(bool);
    200 
    201     bool m_initialPruningComplete;
    202 
    203     void setIconURLForPageURLInSQLDatabase(const String&, const String&);
    204     void setIconIDForPageURLInSQLDatabase(int64_t, const String&);
    205     void removePageURLFromSQLDatabase(const String& pageURL);
    206     int64_t getIconIDForIconURLFromSQLDatabase(const String& iconURL);
    207     int64_t addIconURLToSQLDatabase(const String&);
    208     PassRefPtr<SharedBuffer> getImageDataForIconURLFromSQLDatabase(const String& iconURL);
    209     void removeIconFromSQLDatabase(const String& iconURL);
    210     void writeIconSnapshotToSQLDatabase(const IconSnapshot&);
    211 
    212     // The client is set by the main thread before the thread starts, and from then on is only used by the sync thread
    213     IconDatabaseClient* m_client;
    214 
    215     SQLiteDatabase m_syncDB;
    216 
    217     // Track whether the "Safari 2" import is complete and/or set in the database
    218     bool m_imported;
    219     bool m_isImportedSet;
    220 
    221     OwnPtr<SQLiteStatement> m_setIconIDForPageURLStatement;
    222     OwnPtr<SQLiteStatement> m_removePageURLStatement;
    223     OwnPtr<SQLiteStatement> m_getIconIDForIconURLStatement;
    224     OwnPtr<SQLiteStatement> m_getImageDataForIconURLStatement;
    225     OwnPtr<SQLiteStatement> m_addIconToIconInfoStatement;
    226     OwnPtr<SQLiteStatement> m_addIconToIconDataStatement;
    227     OwnPtr<SQLiteStatement> m_getImageDataStatement;
    228     OwnPtr<SQLiteStatement> m_deletePageURLsForIconURLStatement;
    229     OwnPtr<SQLiteStatement> m_deleteIconFromIconInfoStatement;
    230     OwnPtr<SQLiteStatement> m_deleteIconFromIconDataStatement;
    231     OwnPtr<SQLiteStatement> m_updateIconInfoStatement;
    232     OwnPtr<SQLiteStatement> m_updateIconDataStatement;
    233     OwnPtr<SQLiteStatement> m_setIconInfoStatement;
    234     OwnPtr<SQLiteStatement> m_setIconDataStatement;
    235 #endif // ENABLE(ICONDATABASE)
    236 };
    237 
    238 // Function to obtain the global icon database.
    239 IconDatabase* iconDatabase();
    240 
    241 } // namespace WebCore
    242 
    243 #endif // IconDatabase_h
    244