]> git.saurik.com Git - apple/configd.git/blob - Plugins/common/InterfaceNamerControlPrefs.c
configd-1061.0.2.tar.gz
[apple/configd.git] / Plugins / common / InterfaceNamerControlPrefs.c
1 /*
2 * Copyright (c) 2017-2019 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * InterfaceNamerControlPrefs.c
26 * - definitions for accessing InterfaceNamer control preferences
27 */
28
29 /*
30 * Modification History
31 *
32 * January 12, 2017 Allan Nathanson (ajn@apple.com)
33 * - created
34 */
35
36 #include <TargetConditionals.h>
37 #include <SystemConfiguration/SystemConfiguration.h>
38 #include <SystemConfiguration/SCPrivate.h>
39 #include <SystemConfiguration/scprefs_observer.h>
40 #include "InterfaceNamerControlPrefs.h"
41
42 /*
43 * kInterfaceNamerControlPrefsID
44 * - identifies the InterfaceNamer preferences file that contains 'AllowNewInterfaces'
45 */
46 #define kInterfaceNamerControlPrefsIDStr "com.apple.InterfaceNamer.control.plist"
47 #define kInterfaceNamerControlPrefsID CFSTR(kInterfaceNamerControlPrefsIDStr)
48
49 /*
50 * kAllowNewInterfaces
51 * - indicates whether InterfaceNamer is allowed to create new interfaces
52 * while the screen is locked or not
53 */
54 #define kAllowNewInterfaces CFSTR("AllowNewInterfaces")
55
56 static SCPreferencesRef S_prefs;
57 static InterfaceNamerControlPrefsCallBack S_callback;
58
59 static SCPreferencesRef
60 InterfaceNamerControlPrefsGet(void)
61 {
62 if (S_prefs == NULL) {
63 InterfaceNamerControlPrefsInit(NULL, NULL);
64 }
65
66 return (S_prefs);
67 }
68
69 static void
70 prefs_changed(void * arg)
71 {
72 #pragma unused(arg)
73 /* get the current value */
74 if (S_callback != NULL) {
75 (*S_callback)(S_prefs);
76 }
77
78 return;
79 }
80
81 #if TARGET_OS_IPHONE
82 /*
83 * kInterfaceNamerControlManangedPrefsID
84 * - identifies the location of the managed preferences file
85 */
86 #define kManagedPrefsDirStr "/Library/Managed Preferences/mobile/"
87 #define kInterfaceNamerControlManagedPrefsID CFSTR(kManagedPrefsDirStr \
88 kInterfaceNamerControlPrefsIDStr)
89 static SCPreferencesRef S_managed_prefs;
90
91 static SCPreferencesRef
92 InterfaceNamerControlManagedPrefsGet(void)
93 {
94 if (S_managed_prefs == NULL) {
95 CFMutableDictionaryRef options;
96
97 options = CFDictionaryCreateMutable(NULL,
98 0,
99 &kCFTypeDictionaryKeyCallBacks,
100 &kCFTypeDictionaryValueCallBacks);
101 CFDictionarySetValue(options, kSCPreferencesOptionRemoveWhenEmpty, kCFBooleanTrue);
102 S_managed_prefs = SCPreferencesCreateWithOptions(NULL,
103 CFSTR("InterfaceNamerControlPrefs"),
104 kInterfaceNamerControlManagedPrefsID,
105 NULL,
106 options);
107 CFRelease(options);
108 }
109 return (S_managed_prefs);
110 }
111
112 static void
113 enable_prefs_observer(CFRunLoopRef runloop)
114 {
115 CFRunLoopSourceContext context;
116 dispatch_queue_t queue;
117 CFRunLoopSourceRef source;
118
119 memset(&context, 0, sizeof(context));
120 context.perform = prefs_changed;
121 source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
122 CFRunLoopAddSource(runloop, source, kCFRunLoopCommonModes);
123 queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
124 _scprefs_observer_watch(scprefs_observer_type_global,
125 kInterfaceNamerControlPrefsIDStr,
126 queue,
127 ^{
128 if (source != NULL) {
129 CFRunLoopSourceSignal(source);
130 if (runloop != NULL) {
131 CFRunLoopWakeUp(runloop);
132 }
133 };
134 });
135 return;
136 }
137
138 #else /* TARGET_OS_IPHONE */
139
140 static void
141 enable_prefs_observer(CFRunLoopRef runloop)
142 {
143 #pragma unused(runloop)
144 return;
145 }
146
147 #endif /* TARGET_OS_IPHONE */
148
149 static void
150 InterfaceNamerControlPrefsChanged(SCPreferencesRef prefs,
151 SCPreferencesNotification type,
152 void *info)
153 {
154 #pragma unused(prefs)
155 #pragma unused(type)
156 #pragma unused(info)
157 prefs_changed(NULL);
158 return;
159 }
160
161 __private_extern__ SCPreferencesRef
162 InterfaceNamerControlPrefsInit(CFRunLoopRef runloop,
163 InterfaceNamerControlPrefsCallBack callback)
164 {
165 CFMutableDictionaryRef options;
166
167 options = CFDictionaryCreateMutable(NULL,
168 0,
169 &kCFTypeDictionaryKeyCallBacks,
170 &kCFTypeDictionaryValueCallBacks);
171 CFDictionarySetValue(options, kSCPreferencesOptionRemoveWhenEmpty, kCFBooleanTrue);
172 S_prefs = SCPreferencesCreateWithOptions(NULL,
173 CFSTR("InterfaceNamerControlPrefs"),
174 kInterfaceNamerControlPrefsID,
175 NULL,
176 options);
177 CFRelease(options);
178
179 if ((runloop != NULL) && (callback != NULL)) {
180 S_callback = callback;
181 if (!SCPreferencesSetCallback(S_prefs, InterfaceNamerControlPrefsChanged, NULL)) {
182 SC_log(LOG_NOTICE, "SCPreferencesSetCallBack() failed: %s", SCErrorString(SCError()));
183 goto done;
184 }
185
186 if (!SCPreferencesScheduleWithRunLoop(S_prefs, runloop, kCFRunLoopCommonModes)) {
187 SC_log(LOG_NOTICE, "SCPreferencesScheduleWithRunLoop() failed: %s", SCErrorString(SCError()));
188 (void) SCPreferencesSetCallback(S_prefs, NULL, NULL);
189 }
190
191 enable_prefs_observer(runloop);
192 }
193
194 done :
195 return (S_prefs);
196 }
197
198 static Boolean
199 InterfaceNamerControlPrefsSave(void)
200 {
201 Boolean saved = FALSE;
202
203 if (S_prefs != NULL) {
204 saved = SCPreferencesCommitChanges(S_prefs);
205 SCPreferencesSynchronize(S_prefs);
206 }
207 return (saved);
208 }
209
210 static CFBooleanRef
211 prefs_get_boolean(CFStringRef key)
212 {
213 CFBooleanRef b = NULL;
214 SCPreferencesRef prefs;
215
216 #if TARGET_OS_IPHONE
217 prefs = InterfaceNamerControlManagedPrefsGet();
218 if (prefs != NULL) {
219 b = SCPreferencesGetValue(prefs, key);
220 b = isA_CFBoolean(b);
221 if (b != NULL) {
222 return (b);
223 }
224 }
225 #endif /* TARGET_OS_IPHONE */
226
227 prefs = InterfaceNamerControlPrefsGet();
228 if (prefs != NULL) {
229 b = SCPreferencesGetValue(prefs, key);
230 b = isA_CFBoolean(b);
231 }
232 return (b);
233 }
234
235 static void
236 prefs_set_boolean(CFStringRef key, CFBooleanRef b)
237 {
238 SCPreferencesRef prefs;
239
240 prefs = InterfaceNamerControlPrefsGet();
241 if (prefs != NULL) {
242 if (isA_CFBoolean(b) == NULL) {
243 SCPreferencesRemoveValue(prefs, key);
244 }
245 else {
246 SCPreferencesSetValue(prefs, key, b);
247 }
248 }
249 return;
250 }
251
252 static void
253 InterfaceNamerControlPrefsRefresh(void)
254 {
255 if (S_prefs != NULL) {
256 SCPreferencesSynchronize(S_prefs);
257 }
258 #if TARGET_OS_IPHONE
259 if (S_managed_prefs != NULL) {
260 SCPreferencesSynchronize(S_managed_prefs);
261 }
262 #endif /* TARGET_OS_IPHONE */
263 return;
264 }
265
266 /**
267 ** Get
268 **/
269 __private_extern__ Boolean
270 InterfaceNamerControlPrefsAllowNewInterfaces(void)
271 {
272 CFBooleanRef b;
273 Boolean allow = FALSE;
274
275 b = prefs_get_boolean(kAllowNewInterfaces);
276 if (b != NULL) {
277 allow = CFBooleanGetValue(b);
278 }
279 /* flush the backing store */
280 InterfaceNamerControlPrefsRefresh();
281 return (allow);
282 }
283
284 /**
285 ** Set
286 **/
287 __private_extern__ Boolean
288 InterfaceNamerControlPrefsSetAllowNewInterfaces(Boolean allow)
289 {
290 if (allow) {
291 prefs_set_boolean(kAllowNewInterfaces, kCFBooleanTrue);
292 } else {
293 prefs_set_boolean(kAllowNewInterfaces, NULL);
294 }
295 return (InterfaceNamerControlPrefsSave());
296 }