+2008-02-28 Adam Roben <aroben@apple.com>
+
+ Change WebPreferences to be backed by CFPreferences
+
+ Reviewed by Ada, Geoff, Steve, and Darin.
+
+ * WebPreferenceKeysPrivate.h:
+ * WebPreferences.cpp:
+ (WebPreferences::sharedStandardPreferences): Changed to call
+ setAutoSaves(TRUE) before calling load(). This ensures that the
+ preferences being migrated to CFPreferences are saved to disk.
+ (WebPreferences::valueForKey): Changed to return a RetainPtr to ensure
+ that the refcount is managed properly. Now attempts to retrieve a
+ value from CFPreferences before falling back to the default settings.
+ (WebPreferences::setValueForKey): Now saves the value in
+ CFPreferences if m_autoSaves is true.
+ (WebPreferences::stringValueForKey): Updated for valueForKey changes.
+ (WebPreferences::integerValueForKey): DItto.
+ (WebPreferences::boolValueForKey): Ditto.
+ (WebPreferences::floatValueForKey): Ditto.
+ (WebPreferences::save): Now simply calls CFPreferencesAppSynchronize.
+ (WebPreferences::load): Always initializes m_privatePrefs to an empty
+ CFMutableDictionary.
+ (WebPreferences::migrateWebKitPreferencesToCFPreferences): Migrates
+ preferences from our old custom plist to CFPreferences and then
+ deletes our custom plist, if the migration has never occurred before.
+ (WebPreferences::copyWebKitPreferencesToCFPreferences): Copies
+ preferences to CFPreferences. If we've never migrated the default
+ settings from Safari 3 Beta before, we omit them from this copying
+ procedure.
+ * WebPreferences.h:
+
2008-02-28 Adam Roben <aroben@apple.com>
Refactor value <-> CFNumber conversions into some helper functions
#include <tchar.h>
#include <WebKitSystemInterface/WebKitSystemInterface.h>
#include <wtf/HashMap.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/Vector.h>
+#include <wtf/OwnArrayPtr.h>
using namespace WebCore;
-static const String& preferencesPath()
+static const String& oldPreferencesPath()
{
static String path = pathByAppendingComponent(roamingUserSpecificStorageDirectory(), "WebKitPreferences.plist");
return path;
static WebPreferences* standardPreferences;
if (!standardPreferences) {
standardPreferences = WebPreferences::createInstance();
- standardPreferences->load();
standardPreferences->setAutosaves(TRUE);
+ standardPreferences->load();
}
return standardPreferences;
defaultSettings = defaults;
}
-const void* WebPreferences::valueForKey(CFStringRef key)
+RetainPtr<CFPropertyListRef> WebPreferences::valueForKey(CFStringRef key)
{
- const void* value = CFDictionaryGetValue(m_privatePrefs.get(), key);
- if (!value)
- value = CFDictionaryGetValue(defaultSettings, key);
+ RetainPtr<CFPropertyListRef> value = CFDictionaryGetValue(m_privatePrefs.get(), key);
+ if (value)
+ return value;
- return value;
+ value.adoptCF(CFPreferencesCopyAppValue(key, kCFPreferencesCurrentApplication));
+ if (value)
+ return value;
+
+ return CFDictionaryGetValue(defaultSettings, key);
}
void WebPreferences::setValueForKey(CFStringRef key, CFPropertyListRef value)
{
CFDictionarySetValue(m_privatePrefs.get(), key, value);
- if (m_autoSaves)
+ if (m_autoSaves) {
+ CFPreferencesSetAppValue(key, value, kCFPreferencesCurrentApplication);
save();
+ }
}
BSTR WebPreferences::stringValueForKey(CFStringRef key)
{
- CFStringRef str = (CFStringRef)valueForKey(key);
+ RetainPtr<CFPropertyListRef> value = valueForKey(key);
- if (!str || (CFGetTypeID(str) != CFStringGetTypeID()))
+ if (!value || (CFGetTypeID(value.get()) != CFStringGetTypeID()))
return 0;
+ CFStringRef str = static_cast<CFStringRef>(value.get());
+
CFIndex length = CFStringGetLength(str);
const UniChar* uniChars = CFStringGetCharactersPtr(str);
if (uniChars)
int WebPreferences::integerValueForKey(CFStringRef key)
{
- return numberValueForPreferencesValue<int>(valueForKey(key));
+ return numberValueForPreferencesValue<int>(valueForKey(key).get());
}
BOOL WebPreferences::boolValueForKey(CFStringRef key)
{
- return booleanValueForPreferencesValue(valueForKey(key));
+ return booleanValueForPreferencesValue(valueForKey(key).get());
}
float WebPreferences::floatValueForKey(CFStringRef key)
{
- return numberValueForPreferencesValue<float>(valueForKey(key));
+ return numberValueForPreferencesValue<float>(valueForKey(key).get());
}
LONGLONG WebPreferences::longlongValueForKey(CFStringRef key)
{
- return numberValueForPreferencesValue<LONGLONG>(valueForKey(key));
+ return numberValueForPreferencesValue<LONGLONG>(valueForKey(key).get());
}
void WebPreferences::setStringValue(CFStringRef key, LPCTSTR value)
static BSTR webPreferencesRemovedNotification = SysAllocString(WebPreferencesRemovedNotification);
return webPreferencesRemovedNotification;
}
+
void WebPreferences::save()
{
- RetainPtr<CFWriteStreamRef> stream(AdoptCF,
- CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorDefault, kCFAllocatorDefault));
- if (!stream)
- return;
-
- if (!CFWriteStreamOpen(stream.get()))
- return;
+ CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
+}
- if (!CFPropertyListWriteToStream(m_privatePrefs.get(), stream.get(), kCFPropertyListXMLFormat_v1_0, 0)) {
- CFWriteStreamClose(stream.get());
- return;
- }
- CFWriteStreamClose(stream.get());
+void WebPreferences::load()
+{
+ initializeDefaultSettings();
- RetainPtr<CFDataRef> dataRef(AdoptCF,
- (CFDataRef)CFWriteStreamCopyProperty(stream.get(), kCFStreamPropertyDataWritten));
- if (!dataRef)
- return;
+ m_privatePrefs.adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
- safeCreateFile(preferencesPath(), dataRef.get());
+ migrateWebKitPreferencesToCFPreferences();
}
-void WebPreferences::load()
+void WebPreferences::migrateWebKitPreferencesToCFPreferences()
{
- initializeDefaultSettings();
+ CFStringRef didMigrateKey = CFSTR(WebKitDidMigrateWebKitPreferencesToCFPreferencesPreferenceKey);
+ if (boolValueForKey(didMigrateKey))
+ return;
+ bool oldValue = m_autoSaves;
+ m_autoSaves = true;
+ setBoolValue(didMigrateKey, TRUE);
+ m_autoSaves = oldValue;
- CString path = preferencesPath().utf8();
+ CString path = oldPreferencesPath().utf8();
RetainPtr<CFURLRef> urlRef(AdoptCF, CFURLCreateFromFileSystemRepresentation(0, reinterpret_cast<const UInt8*>(path.data()), path.length(), false));
if (!urlRef)
return;
RetainPtr<CFReadStreamRef> stream(AdoptCF, CFReadStreamCreateWithFile(0, urlRef.get()));
- if (!stream)
+ if (!stream)
return;
- if (CFReadStreamOpen(stream.get())) {
- CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0 | kCFPropertyListXMLFormat_v1_0;
- RetainPtr<CFPropertyListRef> plist(AdoptCF, CFPropertyListCreateFromStream(0, stream.get(), 0, kCFPropertyListMutableContainersAndLeaves, &format, 0));
- CFReadStreamClose(stream.get());
-
- if (CFGetTypeID(plist.get()) == CFDictionaryGetTypeID())
- m_privatePrefs.adoptCF(const_cast<CFMutableDictionaryRef>(reinterpret_cast<CFDictionaryRef>(plist.releaseRef())));
- }
-
- if (!m_privatePrefs)
- m_privatePrefs.adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-
- migrateDefaultSettingsFromSafari3Beta();
-}
-
-void WebPreferences::migrateDefaultSettingsFromSafari3Beta()
-{
- // The "migration" happening here is a one-time removal of any default values
- // that were stored in the user's preferences due to <rdar://problem/5214504>.
-
- ASSERT(defaultSettings);
- if (!m_privatePrefs)
+ if (!CFReadStreamOpen(stream.get()))
return;
- CFStringRef didMigrateKey = CFSTR(WebKitDidMigrateDefaultSettingsFromSafari3BetaPreferenceKey);
- if (boolValueForKey(didMigrateKey))
+ CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0 | kCFPropertyListXMLFormat_v1_0;
+ RetainPtr<CFPropertyListRef> plist(AdoptCF, CFPropertyListCreateFromStream(0, stream.get(), 0, kCFPropertyListMutableContainersAndLeaves, &format, 0));
+ CFReadStreamClose(stream.get());
+
+ if (!plist || CFGetTypeID(plist.get()) != CFDictionaryGetTypeID())
return;
- removeValuesMatchingDefaultSettings();
+ copyWebKitPreferencesToCFPreferences(static_cast<CFDictionaryRef>(plist.get()));
- bool oldValue = m_autoSaves;
- m_autoSaves = true;
- setBoolValue(didMigrateKey, TRUE);
- m_autoSaves = oldValue;
+ deleteFile(oldPreferencesPath());
}
-void WebPreferences::removeValuesMatchingDefaultSettings()
+void WebPreferences::copyWebKitPreferencesToCFPreferences(CFDictionaryRef dict)
{
- ASSERT(m_privatePrefs);
+ ASSERT_ARG(dict, dict);
- int count = CFDictionaryGetCount(m_privatePrefs.get());
+ int count = CFDictionaryGetCount(dict);
if (count <= 0)
return;
- Vector<CFTypeRef> keys(count);
- Vector<CFTypeRef> values(count);
- CFDictionaryGetKeysAndValues(m_privatePrefs.get(), keys.data(), values.data());
+ CFStringRef didRemoveDefaultsKey = CFSTR(WebKitDidMigrateDefaultSettingsFromSafari3BetaPreferenceKey);
+ bool omitDefaults = !booleanValueForPreferencesValue(CFDictionaryGetValue(dict, didRemoveDefaultsKey));
+
+ OwnArrayPtr<CFTypeRef> keys(new CFTypeRef[count]);
+ OwnArrayPtr<CFTypeRef> values(new CFTypeRef[count]);
+ CFDictionaryGetKeysAndValues(dict, keys.get(), values.get());
for (int i = 0; i < count; ++i) {
- if (!values[i])
+ if (!keys[i] || !values[i] || CFGetTypeID(keys[i]) != CFStringGetTypeID())
continue;
- CFTypeRef defaultValue = CFDictionaryGetValue(defaultSettings, keys[i]);
- if (!defaultValue)
- continue;
+ if (omitDefaults) {
+ CFTypeRef defaultValue = CFDictionaryGetValue(defaultSettings, keys[i]);
+ if (defaultValue && CFEqual(defaultValue, values[i]))
+ continue;
+ }
- if (CFEqual(values[i], defaultValue))
- CFDictionaryRemoveValue(m_privatePrefs.get(), keys[i]);
+ setValueForKey(static_cast<CFStringRef>(keys[i]), values[i]);
}
}