18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 2635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * its contributors may be used to endorse or promote products derived 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * from this software without specific prior written permission. 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "WebIconDatabaseInternal.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "WebIconDatabaseClient.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "WebIconDatabaseDelegate.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "WebKitLogging.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "WebKitNSStringExtras.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "WebNSFileManagerExtras.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "WebNSNotificationCenterExtras.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "WebNSURLExtras.h" 382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#import "WebPreferencesPrivate.h" 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "WebTypesInternal.h" 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <WebCore/IconDatabase.h> 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <WebCore/Image.h> 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <WebCore/IntSize.h> 43dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#import <WebCore/SharedBuffer.h> 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <WebCore/ThreadCheck.h> 4521939df44de1705786c545cd1bf519d47250322dBen Murdoch#import <runtime/InitializeThreading.h> 4621939df44de1705786c545cd1bf519d47250322dBen Murdoch#import <wtf/Threading.h> 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WebCore; 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSString * const WebIconDatabaseVersionKey = @"WebIconDatabaseVersion"; 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSString * const WebURLToIconURLKey = @"WebSiteURLToIconURLKey"; 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSString *WebIconDatabaseDidAddIconNotification = @"WebIconDatabaseDidAddIconNotification"; 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSString *WebIconNotificationUserInfoURLKey = @"WebIconNotificationUserInfoURLKey"; 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSString *WebIconDatabaseDidRemoveAllIconsNotification = @"WebIconDatabaseDidRemoveAllIconsNotification"; 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSString *WebIconDatabaseDirectoryDefaultsKey = @"WebIconDatabaseDirectoryDefaultsKey"; 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSString *WebIconDatabaseImportDirectoryDefaultsKey = @"WebIconDatabaseImportDirectoryDefaultsKey"; 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSString *WebIconDatabaseEnabledDefaultsKey = @"WebIconDatabaseEnabled"; 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSString *WebIconDatabasePath = @"~/Library/Icons"; 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSSize WebIconSmallSize = {16, 16}; 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSSize WebIconMediumSize = {32, 32}; 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSSize WebIconLargeSize = {128, 128}; 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define UniqueFilePathSize (34) 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic WebIconDatabaseClient* defaultClient() 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if ENABLE(ICONDATABASE) 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static WebIconDatabaseClient* defaultClient = new WebIconDatabaseClient(); 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return defaultClient; 740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return 0; 760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@interface WebIconDatabase (WebReallyInternal) 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)_sendNotificationForURL:(NSString *)URL; 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)_sendDidRemoveAllIconsNotification; 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSImage *)_iconForFileURL:(NSString *)fileURL withSize:(NSSize)size; 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)_resetCachedWebPreferences:(NSNotification *)notification; 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSImage *)_largestIconFromDictionary:(NSMutableDictionary *)icons; 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSMutableDictionary *)_iconsBySplittingRepresentationsOfIcon:(NSImage *)icon; 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSImage *)_iconFromDictionary:(NSMutableDictionary *)icons forSize:(NSSize)size cache:(BOOL)cache; 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)_scaleIcon:(NSImage *)icon toSize:(NSSize)size; 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSString *)_databaseDirectory; 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@end 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@implementation WebIconDatabase 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9321939df44de1705786c545cd1bf519d47250322dBen Murdoch+ (void)initialize 9421939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 9521939df44de1705786c545cd1bf519d47250322dBen Murdoch JSC::initializeThreading(); 9621939df44de1705786c545cd1bf519d47250322dBen Murdoch WTF::initializeMainThreadToProcessMainThread(); 9721939df44de1705786c545cd1bf519d47250322dBen Murdoch} 9821939df44de1705786c545cd1bf519d47250322dBen Murdoch 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project+ (WebIconDatabase *)sharedIconDatabase 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static WebIconDatabase *database = nil; 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!database) 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project database = [[WebIconDatabase alloc] init]; 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return database; 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 107967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch- (id)init 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [super init]; 110563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark WebCoreThreadViolationCheckRoundOne(); 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project _private = [[WebIconDatabasePrivate alloc] init]; 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check the user defaults and see if the icon database should even be enabled. 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Inform the bridge and, if we're disabled, bail from init right here 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // <rdar://problem/4741419> - IconDatabase should be disabled by default 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSDictionary *initialDefaults = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithBool:YES], WebIconDatabaseEnabledDefaultsKey, nil]; 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [defaults registerDefaults:initialDefaults]; 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [initialDefaults release]; 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project BOOL enabled = [defaults boolForKey:WebIconDatabaseEnabledDefaultsKey]; 12281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().setEnabled(enabled); 123635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (enabled) 124635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project [self _startUpIconDatabase]; 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return self; 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSImage *)iconForURL:(NSString *)URL withSize:(NSSize)size cache:(BOOL)cache 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_MAIN_THREAD(); 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(size.width); 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(size.height); 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!URL || ![self isEnabled]) 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return [self defaultIconForURL:URL withSize:size]; 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME - <rdar://problem/4697934> - Move the handling of FileURLs to WebCore and implement in ObjC++ 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ([URL _webkit_isFileURL]) 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return [self _iconForFileURL:URL withSize:size]; 1402bde8e466a4451c7319e3a072d118917957d6554Steve Block 1412bde8e466a4451c7319e3a072d118917957d6554Steve Block if (Image* image = iconDatabase().synchronousIconForPageURL(URL, IntSize(size))) 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (NSImage *icon = webGetNSImage(image, size)) 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return icon; 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return [self defaultIconForURL:URL withSize:size]; 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSImage *)iconForURL:(NSString *)URL withSize:(NSSize)size 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return [self iconForURL:URL withSize:size cache:YES]; 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSString *)iconURLForURL:(NSString *)URL 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 154635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (![self isEnabled]) 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return nil; 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_MAIN_THREAD(); 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1582bde8e466a4451c7319e3a072d118917957d6554Steve Block return iconDatabase().synchronousIconURLForPageURL(URL); 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSImage *)defaultIconWithSize:(NSSize)size 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_MAIN_THREAD(); 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(size.width); 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(size.height); 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Image* image = iconDatabase().defaultIcon(IntSize(size)); 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return image ? image->getNSImage() : nil; 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSImage *)defaultIconForURL:(NSString *)URL withSize:(NSSize)size 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (_private->delegateImplementsDefaultIconForURL) 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return [_private->delegate webIconDatabase:self defaultIconForURL:URL withSize:size]; 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return [self defaultIconWithSize:size]; 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)retainIconForURL:(NSString *)URL 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_MAIN_THREAD(); 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(URL); 182635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (![self isEnabled]) 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().retainIconForPageURL(URL); 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)releaseIconForURL:(NSString *)pageURL 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_MAIN_THREAD(); 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(pageURL); 192635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (![self isEnabled]) 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().releaseIconForPageURL(pageURL); 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project+ (void)delayDatabaseCleanup 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_MAIN_THREAD(); 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IconDatabase::delayDatabaseCleanup(); 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project+ (void)allowDatabaseCleanup 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_MAIN_THREAD(); 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IconDatabase::allowDatabaseCleanup(); 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)setDelegate:(id)delegate 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project _private->delegate = delegate; 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project _private->delegateImplementsDefaultIconForURL = [delegate respondsToSelector:@selector(webIconDatabase:defaultIconForURL:withSize:)]; 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (id)delegate 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return _private->delegate; 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@end 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@implementation WebIconDatabase (WebPendingPublic) 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 228635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project- (BOOL)isEnabled 229635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 23081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return iconDatabase().isEnabled(); 231635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 232635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 233635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project- (void)setEnabled:(BOOL)flag 234635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 235635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project BOOL currentlyEnabled = [self isEnabled]; 236635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (currentlyEnabled && !flag) { 23781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().setEnabled(false); 238635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project [self _shutDownIconDatabase]; 239635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else if (!currentlyEnabled && flag) { 24081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().setEnabled(true); 241635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project [self _startUpIconDatabase]; 242635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 243635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 244635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)removeAllIcons 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_MAIN_THREAD(); 248635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (![self isEnabled]) 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Via the IconDatabaseClient interface, removeAllIcons() will send the WebIconDatabaseDidRemoveAllIconsNotification 25281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().removeAllIcons(); 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@end 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@implementation WebIconDatabase (WebPrivate) 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project+ (void)_checkIntegrityBeforeOpening 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2612bde8e466a4451c7319e3a072d118917957d6554Steve Block IconDatabase::checkIntegrityBeforeOpening(); 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@end 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@implementation WebIconDatabase (WebInternal) 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)_sendNotificationForURL:(NSString *)URL 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(URL); 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSDictionary *userInfo = [NSDictionary dictionaryWithObject:URL 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project forKey:WebIconNotificationUserInfoURLKey]; 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:WebIconDatabaseDidAddIconNotification 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object:self 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project userInfo:userInfo]; 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)_sendDidRemoveAllIconsNotification 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:WebIconDatabaseDidRemoveAllIconsNotification 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object:self 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project userInfo:nil]; 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 287635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project- (void)_startUpIconDatabase 288635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 28981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().setClient(defaultClient()); 290635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 291635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Figure out the directory we should be using for the icon.db 292635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NSString *databaseDirectory = [self _databaseDirectory]; 293635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Rename legacy icon database files to the new icon database name 295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project BOOL isDirectory = NO; 296635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NSString *legacyDB = [databaseDirectory stringByAppendingPathComponent:@"icon.db"]; 297635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NSFileManager *defaultManager = [NSFileManager defaultManager]; 298635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if ([defaultManager fileExistsAtPath:legacyDB isDirectory:&isDirectory] && !isDirectory) { 2992bde8e466a4451c7319e3a072d118917957d6554Steve Block NSString *newDB = [databaseDirectory stringByAppendingPathComponent:IconDatabase::defaultDatabaseFilename()]; 300635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (![defaultManager fileExistsAtPath:newDB]) 301635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project rename([legacyDB fileSystemRepresentation], [newDB fileSystemRepresentation]); 302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 303635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 304635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Set the private browsing pref then open the WebCore icon database 30581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().setPrivateBrowsingEnabled([[WebPreferences standardPreferences] privateBrowsingEnabled]); 3062bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!iconDatabase().open(databaseDirectory, IconDatabase::defaultDatabaseFilename())) 307635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("Unable to open icon database"); 308635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 309635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Register for important notifications 310635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project [[NSNotificationCenter defaultCenter] addObserver:self 311635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project selector:@selector(_applicationWillTerminate:) 312635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project name:NSApplicationWillTerminateNotification 313635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project object:NSApp]; 314635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project [[NSNotificationCenter defaultCenter] addObserver:self 315635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project selector:@selector(_resetCachedWebPreferences:) 3162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch name:WebPreferencesChangedInternalNotification 317635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project object:nil]; 318635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 319635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 320635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project- (void)_shutDownIconDatabase 321635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 322635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Unregister for important notifications 323635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project [[NSNotificationCenter defaultCenter] removeObserver:self 324635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project name:NSApplicationWillTerminateNotification 325635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project object:NSApp]; 326635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project [[NSNotificationCenter defaultCenter] removeObserver:self 3272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch name:WebPreferencesChangedInternalNotification 328635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project object:nil]; 329635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 330635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)_applicationWillTerminate:(NSNotification *)notification 3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 33381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().close(); 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSImage *)_iconForFileURL:(NSString *)file withSize:(NSSize)size 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_MAIN_THREAD(); 3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(size.width); 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(size.height); 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; 3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSString *path = [[NSURL _web_URLWithDataAsString:file] path]; 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSString *suffix = [path pathExtension]; 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSImage *icon = nil; 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ([suffix _webkit_isCaseInsensitiveEqualToString:@"htm"] || [suffix _webkit_isCaseInsensitiveEqualToString:@"html"]) { 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!_private->htmlIcons) { 3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project icon = [workspace iconForFileType:@"html"]; 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project _private->htmlIcons = [[self _iconsBySplittingRepresentationsOfIcon:icon] retain]; 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project icon = [self _iconFromDictionary:_private->htmlIcons forSize:size cache:YES]; 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!path || ![path isAbsolutePath]) { 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Return the generic icon when there is no path. 3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project icon = [workspace iconForFileType:NSFileTypeForHFSTypeCode(kGenericDocumentIcon)]; 3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project icon = [workspace iconForFile:path]; 3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [self _scaleIcon:icon toSize:size]; 3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return icon; 3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)_resetCachedWebPreferences:(NSNotification *)notification 3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project BOOL privateBrowsingEnabledNow = [[WebPreferences standardPreferences] privateBrowsingEnabled]; 36981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().setPrivateBrowsingEnabled(privateBrowsingEnabledNow); 3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSImage *)_largestIconFromDictionary:(NSMutableDictionary *)icons 3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(icons); 3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSEnumerator *enumerator = [icons keyEnumerator]; 3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSValue *currentSize, *largestSize=nil; 3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float largestSizeArea=0; 3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while ((currentSize = [enumerator nextObject]) != nil) { 3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSSize currentSizeSize = [currentSize sizeValue]; 3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float currentSizeArea = currentSizeSize.width * currentSizeSize.height; 3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if(!largestSizeArea || (currentSizeArea > largestSizeArea)){ 3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project largestSize = currentSize; 3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project largestSizeArea = currentSizeArea; 3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return [icons objectForKey:largestSize]; 3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSMutableDictionary *)_iconsBySplittingRepresentationsOfIcon:(NSImage *)icon 3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(icon); 3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSMutableDictionary *icons = [NSMutableDictionary dictionary]; 3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSEnumerator *enumerator = [[icon representations] objectEnumerator]; 3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSImageRep *rep; 3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while ((rep = [enumerator nextObject]) != nil) { 4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSSize size = [rep size]; 4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSImage *subIcon = [[NSImage alloc] initWithSize:size]; 4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [subIcon addRepresentation:rep]; 4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [icons setObject:subIcon forKey:[NSValue valueWithSize:size]]; 4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [subIcon release]; 4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if([icons count] > 0) 4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return icons; 4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ERROR("icon has no representations"); 4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return nil; 4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSImage *)_iconFromDictionary:(NSMutableDictionary *)icons forSize:(NSSize)size cache:(BOOL)cache 4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(size.width); 4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(size.height); 4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSImage *icon = [icons objectForKey:[NSValue valueWithSize:size]]; 4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if(!icon){ 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project icon = [[[self _largestIconFromDictionary:icons] copy] autorelease]; 4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [self _scaleIcon:icon toSize:size]; 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if(cache){ 4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [icons setObject:icon forKey:[NSValue valueWithSize:size]]; 4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return icon; 4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)_scaleIcon:(NSImage *)icon toSize:(NSSize)size 4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(size.width); 4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(size.height); 4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if !LOG_DISABLED 4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project double start = CFAbsoluteTimeGetCurrent(); 4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [icon setScalesWhenResized:YES]; 4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [icon setSize:size]; 4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if !LOG_DISABLED 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project double duration = CFAbsoluteTimeGetCurrent() - start; 4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG(Timing, "scaling icon took %f seconds.", duration); 4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// This hashing String->filename algorithm came from WebFileDatabase.m and is what was used in the 4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// WebKit Icon Database 4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void legacyIconDatabaseFilePathForKey(id key, char *buffer) 4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char *s; 4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UInt32 hash1; 4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UInt32 hash2; 4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFIndex len; 4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFIndex cnt; 4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project s = [[[[key description] lowercaseString] stringByStandardizingPath] UTF8String]; 4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project len = strlen(s); 4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // compute first hash 4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hash1 = len; 4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (cnt = 0; cnt < len; cnt++) { 4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hash1 += (hash1 << 8) + s[cnt]; 4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hash1 += (hash1 << (len & 31)); 4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // compute second hash 4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hash2 = len; 4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (cnt = 0; cnt < len; cnt++) { 4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hash2 = (37 * hash2) ^ s[cnt]; 4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef __LP64__ 4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project snprintf(buffer, UniqueFilePathSize, "%.2u/%.2u/%.10u-%.10u.cache", ((hash1 & 0xff) >> 4), ((hash2 & 0xff) >> 4), hash1, hash2); 4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project snprintf(buffer, UniqueFilePathSize, "%.2lu/%.2lu/%.10lu-%.10lu.cache", ((hash1 & 0xff) >> 4), ((hash2 & 0xff) >> 4), hash1, hash2); 4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// This method of getting an object from the filesystem is taken from the old 4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// WebKit Icon Database 4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic id objectFromPathForKey(NSString *databasePath, id key) 4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(key); 4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project id result = nil; 4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Use the key->filename hashing the old WebKit IconDatabase used 4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char uniqueKey[UniqueFilePathSize]; 4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project legacyIconDatabaseFilePathForKey(key, uniqueKey); 4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Get the data from this file and setup for the un-archiving 4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSString *filePath = [[NSString alloc] initWithFormat:@"%@/%s", databasePath, uniqueKey]; 4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSData *data = [[NSData alloc] initWithContentsOfFile:filePath]; 5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSUnarchiver *unarchiver = nil; 5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project @try { 5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (data) { 5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unarchiver = [[NSUnarchiver alloc] initForReadingWithData:data]; 5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (unarchiver) { 5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project id fileKey = [unarchiver decodeObject]; 5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ([fileKey isEqual:key]) { 5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project id object = [unarchiver decodeObject]; 5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (object) { 5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Decoded objects go away when the unarchiver does, so we need to 5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // retain this so we can return it to our caller. 5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = [[object retain] autorelease]; 5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG(IconDatabase, "read disk cache file - %@", key); 5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } @catch (NSException *localException) { 5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG(IconDatabase, "cannot unarchive cache file - %@", key); 5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = nil; 5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [unarchiver release]; 5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [data release]; 5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [filePath release]; 5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic NSData* iconDataFromPathForIconURL(NSString *databasePath, NSString *iconURLString) 5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iconURLString); 5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(databasePath); 5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSData *iconData = objectFromPathForKey(databasePath, iconURLString); 5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ((id)iconData == (id)[NSNull null]) 5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return nil; 5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return iconData; 5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (NSString *)_databaseDirectory 5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Figure out the directory we should be using for the icon.db 5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSString *databaseDirectory = [defaults objectForKey:WebIconDatabaseDirectoryDefaultsKey]; 5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!databaseDirectory) { 5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project databaseDirectory = WebIconDatabasePath; 5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [defaults setObject:databaseDirectory forKey:WebIconDatabaseDirectoryDefaultsKey]; 5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return [[databaseDirectory stringByExpandingTildeInPath] stringByStandardizingPath]; 5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@end 5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@implementation WebIconDatabasePrivate 5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@end 5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@interface ThreadEnabler : NSObject { 5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project+ (void)enableThreading; 5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)threadEnablingSelector:(id)arg; 5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@end 5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@implementation ThreadEnabler 5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)threadEnablingSelector:(id)arg 5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project+ (void)enableThreading 5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ThreadEnabler *enabler = [[ThreadEnabler alloc] init]; 5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [NSThread detachNewThreadSelector:@selector(threadEnablingSelector:) toTarget:enabler withObject:nil]; 5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [enabler release]; 5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@end 5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool importToWebCoreFormat() 5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Since this is running on a secondary POSIX thread and Cocoa cannot be used multithreaded unless an NSThread has been detached, 5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // make sure that happens here for all WebKit clients 5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (![NSThread isMultiThreaded]) 5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [ThreadEnabler enableThreading]; 5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT([NSThread isMultiThreaded]); 5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Get the directory the old icon database *should* be in 5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSString *databaseDirectory = [defaults objectForKey:WebIconDatabaseImportDirectoryDefaultsKey]; 5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!databaseDirectory) 5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project databaseDirectory = [defaults objectForKey:WebIconDatabaseDirectoryDefaultsKey]; 5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!databaseDirectory) { 6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project databaseDirectory = WebIconDatabasePath; 6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [defaults setObject:databaseDirectory forKey:WebIconDatabaseDirectoryDefaultsKey]; 6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project databaseDirectory = [databaseDirectory stringByExpandingTildeInPath]; 6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // With this directory, get the PageURLToIconURL map that was saved to disk 6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSMutableDictionary *pageURLToIconURL = objectFromPathForKey(databaseDirectory, WebURLToIconURLKey); 6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the retrieved object was not a valid NSMutableDictionary, then we have no valid 6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // icons to import 6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (![pageURLToIconURL isKindOfClass:[NSMutableDictionary class]]) 6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project pageURLToIconURL = nil; 6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!pageURLToIconURL) { 6150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // We found no Safari-2-style icon database. Bail out immediately and do not delete everything 6160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // in whatever directory we ended up looking in! Return true so we won't bother to check again. 6170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // FIXME: We can probably delete all of the code to convert Safari-2-style icon databases now. 6180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return true; 6190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 6200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSEnumerator *enumerator = [pageURLToIconURL keyEnumerator]; 6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSString *url, *iconURL; 6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // First, we'll iterate through the PageURL->IconURL map 6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while ((url = [enumerator nextObject]) != nil) { 6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project iconURL = [pageURLToIconURL objectForKey:url]; 6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!iconURL) 6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 62981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().importIconURLForPageURL(iconURL, url); 63081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (iconDatabase().shouldStopThreadActivity()) 6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Second, we'll get a list of the unique IconURLs we have 6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSMutableSet *iconsOnDiskWithURLs = [NSMutableSet setWithArray:[pageURLToIconURL allValues]]; 6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project enumerator = [iconsOnDiskWithURLs objectEnumerator]; 6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSData *iconData; 6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // And iterate through them, adding the icon data to the new icon database 6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while ((url = [enumerator nextObject]) != nil) { 6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project iconData = iconDataFromPathForIconURL(databaseDirectory, url); 6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (iconData) 64381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().importIconDataForIconURL(SharedBuffer::wrapNSData(iconData), url); 6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This really *shouldn't* happen, so it'd be good to track down why it might happen in a debug build 6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // however, we do know how to handle it gracefully in release 6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ERROR("%@ is marked as having an icon on disk, but we couldn't get the data for it", url); 64881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch iconDatabase().importIconDataForIconURL(0, url); 6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 65081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (iconDatabase().shouldStopThreadActivity()) 6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // After we're done importing old style icons over to webcore icons, we delete the entire directory hierarchy 6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // for the old icon DB (skipping the new iconDB if it is in the same directory) 6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSFileManager *fileManager = [NSFileManager defaultManager]; 6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project enumerator = [[fileManager contentsOfDirectoryAtPath:databaseDirectory error:NULL] objectEnumerator]; 6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6592bde8e466a4451c7319e3a072d118917957d6554Steve Block NSString *databaseFilename = IconDatabase::defaultDatabaseFilename(); 6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project BOOL foundIconDB = NO; 6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSString *file; 6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while ((file = [enumerator nextObject]) != nil) { 6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ([file caseInsensitiveCompare:databaseFilename] == NSOrderedSame) { 6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project foundIconDB = YES; 6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSString *filePath = [databaseDirectory stringByAppendingPathComponent:file]; 6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (![fileManager removeItemAtPath:filePath error:NULL]) 6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ERROR("Failed to delete %@ from old icon directory", filePath); 6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the new iconDB wasn't in that directory, we can delete the directory itself 6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!foundIconDB) 6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rmdir([databaseDirectory fileSystemRepresentation]); 6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNSImage *webGetNSImage(Image* image, NSSize size) 6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_MAIN_THREAD(); 6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(size.width); 6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(size.height); 6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: We're doing the resize here for now because WebCore::Image doesn't yet support resizing/multiple representations 6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This makes it so there's effectively only one size of a particular icon in the system at a time. We should move this 6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // to WebCore::Image at some point. 6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!image) 6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return nil; 6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSImage* nsImage = image->getNSImage(); 6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!nsImage) 6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return nil; 6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!NSEqualSizes([nsImage size], size)) { 6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [nsImage setScalesWhenResized:YES]; 6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [nsImage setSize:size]; 6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return nsImage; 6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 700