]> git.saurik.com Git - apple/configd.git/blob - Plugins/common/InterfaceNamerControlPrefs.c
configd-963.200.27.tar.gz
[apple/configd.git] / Plugins / common / InterfaceNamerControlPrefs.c
1 /*
2 * Copyright (c) 2017, 2018 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 os_activity_t activity;
74
75 activity = os_activity_create("processing InterfaceNamer preference change",
76 OS_ACTIVITY_CURRENT,
77 OS_ACTIVITY_FLAG_DEFAULT);
78 os_activity_scope(activity);
79
80 /* get the current value */
81 if (S_callback != NULL) {
82 (*S_callback)(S_prefs);
83 }
84
85 os_release(activity);
86
87 return;
88 }
89
90 #if TARGET_OS_IPHONE
91 /*
92 * kInterfaceNamerControlManangedPrefsID
93 * - identifies the location of the managed preferences file
94 */
95 #define kManagedPrefsDirStr "/Library/Managed Preferences/mobile/"
96 #define kInterfaceNamerControlManagedPrefsID CFSTR(kManagedPrefsDirStr \
97 kInterfaceNamerControlPrefsIDStr)
98 static SCPreferencesRef S_managed_prefs;
99
100 static SCPreferencesRef
101 InterfaceNamerControlManagedPrefsGet(void)
102 {
103 if (S_managed_prefs == NULL) {
104 CFMutableDictionaryRef options;
105
106 options = CFDictionaryCreateMutable(NULL,
107 0,
108 &kCFTypeDictionaryKeyCallBacks,
109 &kCFTypeDictionaryValueCallBacks);
110 CFDictionarySetValue(options, kSCPreferencesOptionRemoveWhenEmpty, kCFBooleanTrue);
111 S_managed_prefs = SCPreferencesCreateWithOptions(NULL,
112 CFSTR("InterfaceNamerControlPrefs"),
113 kInterfaceNamerControlManagedPrefsID,
114 NULL,
115 options);
116 CFRelease(options);
117 }
118 return (S_managed_prefs);
119 }
120
121 static void
122 enable_prefs_observer(CFRunLoopRef runloop)
123 {
124 CFRunLoopSourceContext context;
125 dispatch_queue_t queue;
126 CFRunLoopSourceRef source;
127
128 bzero(&context, sizeof(context));
129 context.perform = prefs_changed;
130 source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
131 CFRunLoopAddSource(runloop, source, kCFRunLoopCommonModes);
132 queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
133 _scprefs_observer_watch(scprefs_observer_type_global,
134 kInterfaceNamerControlPrefsIDStr,
135 queue,
136 ^{
137 if (source != NULL) {
138 CFRunLoopSourceSignal(source);
139 if (runloop != NULL) {
140 CFRunLoopWakeUp(runloop);
141 }
142 };
143 });
144 return;
145 }
146
147 #else /* TARGET_OS_IPHONE */
148
149 static void
150 enable_prefs_observer(CFRunLoopRef runloop)
151 {
152 #pragma unused(runloop)
153 return;
154 }
155
156 #endif /* TARGET_OS_IPHONE */
157
158 static void
159 InterfaceNamerControlPrefsChanged(SCPreferencesRef prefs,
160 SCPreferencesNotification type,
161 void *info)
162 {
163 #pragma unused(prefs)
164 #pragma unused(type)
165 #pragma unused(info)
166 prefs_changed(NULL);
167 return;
168 }
169
170 __private_extern__ SCPreferencesRef
171 InterfaceNamerControlPrefsInit(CFRunLoopRef runloop,
172 InterfaceNamerControlPrefsCallBack callback)
173 {
174 CFMutableDictionaryRef options;
175
176 options = CFDictionaryCreateMutable(NULL,
177 0,
178 &kCFTypeDictionaryKeyCallBacks,
179 &kCFTypeDictionaryValueCallBacks);
180 CFDictionarySetValue(options, kSCPreferencesOptionRemoveWhenEmpty, kCFBooleanTrue);
181 S_prefs = SCPreferencesCreateWithOptions(NULL,
182 CFSTR("InterfaceNamerControlPrefs"),
183 kInterfaceNamerControlPrefsID,
184 NULL,
185 options);
186 CFRelease(options);
187
188 if ((runloop != NULL) && (callback != NULL)) {
189 S_callback = callback;
190 if (!SCPreferencesSetCallback(S_prefs, InterfaceNamerControlPrefsChanged, NULL)) {
191 SC_log(LOG_NOTICE, "SCPreferencesSetCallBack() failed: %s", SCErrorString(SCError()));
192 goto done;
193 }
194
195 if (!SCPreferencesScheduleWithRunLoop(S_prefs, runloop, kCFRunLoopCommonModes)) {
196 SC_log(LOG_NOTICE, "SCPreferencesScheduleWithRunLoop() failed: %s", SCErrorString(SCError()));
197 (void) SCPreferencesSetCallback(S_prefs, NULL, NULL);
198 }
199
200 enable_prefs_observer(runloop);
201 }
202
203 done :
204 return (S_prefs);
205 }
206
207 static Boolean
208 InterfaceNamerControlPrefsSave(void)
209 {
210 Boolean saved = FALSE;
211
212 if (S_prefs != NULL) {
213 saved = SCPreferencesCommitChanges(S_prefs);
214 SCPreferencesSynchronize(S_prefs);
215 }
216 return (saved);
217 }
218
219 static CFBooleanRef
220 prefs_get_boolean(CFStringRef key)
221 {
222 CFBooleanRef b = NULL;
223 SCPreferencesRef prefs;
224
225 #if TARGET_OS_IPHONE
226 prefs = InterfaceNamerControlManagedPrefsGet();
227 if (prefs != NULL) {
228 b = SCPreferencesGetValue(prefs, key);
229 b = isA_CFBoolean(b);
230 if (b != NULL) {
231 return (b);
232 }
233 }
234 #endif /* TARGET_OS_IPHONE */
235
236 prefs = InterfaceNamerControlPrefsGet();
237 if (prefs != NULL) {
238 b = SCPreferencesGetValue(prefs, key);
239 b = isA_CFBoolean(b);
240 }
241 return (b);
242 }
243
244 static void
245 prefs_set_boolean(CFStringRef key, CFBooleanRef b)
246 {
247 SCPreferencesRef prefs;
248
249 prefs = InterfaceNamerControlPrefsGet();
250 if (prefs != NULL) {
251 if (isA_CFBoolean(b) == NULL) {
252 SCPreferencesRemoveValue(prefs, key);
253 }
254 else {
255 SCPreferencesSetValue(prefs, key, b);
256 }
257 }
258 return;
259 }
260
261 static void
262 InterfaceNamerControlPrefsRefresh(void)
263 {
264 if (S_prefs != NULL) {
265 SCPreferencesSynchronize(S_prefs);
266 }
267 #if TARGET_OS_IPHONE
268 if (S_managed_prefs != NULL) {
269 SCPreferencesSynchronize(S_managed_prefs);
270 }
271 #endif /* TARGET_OS_IPHONE */
272 return;
273 }
274
275 /**
276 ** Get
277 **/
278 __private_extern__ Boolean
279 InterfaceNamerControlPrefsAllowNewInterfaces(void)
280 {
281 CFBooleanRef b;
282 Boolean allow = FALSE;
283
284 b = prefs_get_boolean(kAllowNewInterfaces);
285 if (b != NULL) {
286 allow = CFBooleanGetValue(b);
287 }
288 /* flush the backing store */
289 InterfaceNamerControlPrefsRefresh();
290 return (allow);
291 }
292
293 /**
294 ** Set
295 **/
296 __private_extern__ Boolean
297 InterfaceNamerControlPrefsSetAllowNewInterfaces(Boolean allow)
298 {
299 if (allow) {
300 prefs_set_boolean(kAllowNewInterfaces, kCFBooleanTrue);
301 } else {
302 prefs_set_boolean(kAllowNewInterfaces, NULL);
303 }
304 return (InterfaceNamerControlPrefsSave());
305 }