Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(316)

Side by Side Diff: ios/chrome/app/startup/register_experimental_settings.mm

Issue 2580363002: Upstream Chrome on iOS source code [1/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ios/chrome/app/startup/register_experimental_settings.h"
6
7 #include "base/logging.h"
8 #include "base/mac/bundle_locations.h"
9 #import "base/mac/scoped_nsobject.h"
10 #include "base/strings/sys_string_conversions.h"
11
12 namespace {
13 // Key in the UserDefaults for the Experimental Keys.
14 NSString* kExperimentalKeysKey = @"ExperimentalKeys";
15
16 // Returns YES if a setting value is equivalent to not having the setting at
17 // all. This must always be true for default values, otherwise the experimental
18 // settings will have different default behaviors in stable channel (where the
19 // bundle isn't present).
20 BOOL IsDefaultSettingValueValid(id value) {
21 if (!value)
22 return YES;
23 if ([value isKindOfClass:[NSNumber class]])
24 return [value intValue] == 0;
25 if ([value isKindOfClass:[NSString class]])
26 return [value length] == 0;
27 // Add support for other types as necessary.
28 NOTREACHED() << "Unhandled value type "
29 << base::SysNSStringToUTF8(NSStringFromClass([value class]));
30 return NO;
31 }
32 } // namespace
33
34 @interface RegisterExperimentalSettings ()
35 // Registers all the default values for a single settings file and returns
36 // all the registered keys.
37 + (NSArray*)registerExperimentalSettingsForFile:(NSString*)filepath
38 userDefaults:(NSUserDefaults*)userDefaults;
39 @end
40
41 @implementation RegisterExperimentalSettings
42
43 + (void)registerExperimentalSettingsWithUserDefaults:
44 (NSUserDefaults*)userDefaults
45 bundle:(NSBundle*)bundle {
46 // Save the current app version in user defaults.
47 NSDictionary* infoDictionary = [bundle infoDictionary];
48 NSString* version = [infoDictionary objectForKey:@"CFBundleVersion"];
49 [userDefaults setObject:version forKey:@"Version"];
50
51 NSString* bundlePath = [bundle bundlePath];
52 NSString* settingsFilepath =
53 [bundlePath stringByAppendingPathComponent:@"Settings.bundle"];
54 NSArray* settingsContent =
55 [[NSFileManager defaultManager] contentsOfDirectoryAtPath:settingsFilepath
56 error:NULL];
57 base::scoped_nsobject<NSMutableArray> currentExpKeys(
58 [[NSMutableArray alloc] init]);
59
60 for (NSString* filename in settingsContent) {
61 // Only plist files are preferences definition.
62 if ([[filename pathExtension] isEqualToString:@"plist"]) {
63 NSString* filepath =
64 [settingsFilepath stringByAppendingPathComponent:filename];
65 NSArray* registeredKeys =
66 [self registerExperimentalSettingsForFile:filepath
67 userDefaults:userDefaults];
68 [currentExpKeys addObjectsFromArray:registeredKeys];
69 }
70 }
71
72 // Remove all keys that are no longer used.
73 NSArray* expKeys = [userDefaults arrayForKey:kExperimentalKeysKey];
74 NSMutableSet* expKeysSet = [NSMutableSet setWithArray:expKeys];
75 NSSet* currentExpKeysSet = [NSSet setWithArray:currentExpKeys];
76 [expKeysSet minusSet:currentExpKeysSet];
77 for (NSString* key in expKeysSet) {
78 [userDefaults removeObjectForKey:key];
79 }
80
81 if ([currentExpKeys count] > 0) {
82 [userDefaults setObject:currentExpKeys forKey:kExperimentalKeysKey];
83 } else {
84 [userDefaults removeObjectForKey:kExperimentalKeysKey];
85 }
86 }
87
88 + (NSArray*)registerExperimentalSettingsForFile:(NSString*)filepath
89 userDefaults:(NSUserDefaults*)userDefaults {
90 NSMutableArray* registeredKeys = [NSMutableArray array];
91
92 NSDictionary* rootDictionary =
93 [NSDictionary dictionaryWithContentsOfFile:filepath];
94 // Array with all the preference specifiers. The plist is composed of many
95 // Preference specifiers; one for each preference row in the settings
96 // panel.
97 NSArray* preferencesArray =
98 [rootDictionary objectForKey:@"PreferenceSpecifiers"];
99
100 // Scan thru all the preferences in the plist file.
101 for (NSDictionary* preferenceSpecifier in preferencesArray) {
102 NSString* keyValue = [preferenceSpecifier objectForKey:@"Key"];
103 if (!keyValue)
104 continue;
105
106 id defaultValue = [preferenceSpecifier objectForKey:@"DefaultValue"];
107 // Within the app, the default for all experimental prefs is nil (matching
108 // the behavior of Stable channel, where there is no settings bundle). To
109 // make mistakes obvious, fail if someone tries to set any actual value as
110 // the default.
111 DCHECK(IsDefaultSettingValueValid(defaultValue))
112 << "'" << base::SysNSStringToUTF8([defaultValue description])
113 << "' is not a valid default value for "
114 << base::SysNSStringToUTF8(keyValue);
115
116 [registeredKeys addObject:keyValue];
117
118 // If a default value is set, normalize it to nil.
119 id currentValue = [userDefaults objectForKey:keyValue];
120 if (currentValue &&
121 (!defaultValue || [currentValue isEqual:defaultValue])) {
122 [userDefaults removeObjectForKey:keyValue];
123 }
124 }
125 return registeredKeys;
126 }
127
128 @end
OLDNEW
« no previous file with comments | « ios/chrome/app/startup/register_experimental_settings.h ('k') | ios/chrome/app/startup/setup_debugging.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698