Skip to content

Commit ab5cb5a

Browse files
committed
[android] Improve CFKnownLocations.
The usage of CFKnownLocations from Swift Foundation seems to be reduced to both _kCFKnownLocationUserAny and _kCFKnownLocationUserCurrent. From the public API of Swift Foundation there's no way to get to _kCFKnownLocationUserByName. Supporting UserAny is, therefore, necessary. There are some ways of accessing _kCFKnownLocationUserByName from the CF API, but it seems that the API only allows Current or Any, even if they are not enforced. In any case, Android do not have Unix usernames, so ByName doesn't make sense. The change maps AnyUser into a directory inside the preferences of the HOME of the user, and other user names into another subdirectory. Each app will have their own set of Any and ByName, but at least they are not confussed with the CurrentUser preferences. Additionally, instead of picking up a CFFIXEDUSE_HOME, request the home directory from CFUtilities, since it deals with HOME, HOMEDIR and CFFIXED_HOME appropiedly, since HOME is necessary for many other things. The current code will have aborted the test suite, while the modified code, passes the test suite for UserDefaults.
1 parent 7c9fb6a commit ab5cb5a

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

CoreFoundation/Base.subproj/CFKnownLocations.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <CoreFoundation/CFString.h>
1313
#include "CFPriv.h"
1414
#include "CFInternal.h"
15+
#include "CFUtilities.h"
1516

1617
#include <assert.h>
1718

@@ -93,23 +94,26 @@ CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUs
9394

9495
#elif TARGET_OS_ANDROID
9596

97+
// Android doesn't support users, and apps cannot write outside their
98+
// sandbox. All the preferences will be local to the application, mapping
99+
// "any user" and other users by name to different directories inside the
100+
// sandbox.
101+
CFURLRef userdir = CFCopyHomeDirectoryURL();
96102
switch (user) {
97-
case _kCFKnownLocationUserAny:
98-
case _kCFKnownLocationUserByName:
99-
abort();
100-
case _kCFKnownLocationUserCurrent: {
101-
const char *buffer = getenv("CFFIXED_USER_HOME");
102-
if (buffer == NULL || *buffer == '\0') {
103-
CFLog(__kCFLogAssertion, CFSTR("CFFIXED_USER_HOME is unset"));
104-
HALT;
105-
}
106-
107-
CFURLRef userdir = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (const unsigned char *)buffer, strlen(buffer), true);
108-
location = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("/Apple/Library/Preferences"), kCFURLPOSIXPathStyle, true, userdir);
109-
CFRelease(userdir);
110-
break;
111-
}
103+
case _kCFKnownLocationUserAny:
104+
location = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("/Apple/Library/Preferences/AnyUser"), kCFURLPOSIXPathStyle, true, userdir);
105+
break;
106+
case _kCFKnownLocationUserByName: {
107+
CFURLRef tmp = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("/Apple/Library/Preferences/ByUser"), kCFURLPOSIXPathStyle, true, userdir);
108+
location = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, username, kCFURLPOSIXPathStyle, true, tmp);
109+
CFRelease(tmp);
110+
break;
111+
}
112+
case _kCFKnownLocationUserCurrent:
113+
location = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("/Apple/Library/Preferences"), kCFURLPOSIXPathStyle, true, userdir);
114+
break;
112115
}
116+
CFRelease(userdir);
113117

114118
#else
115119

0 commit comments

Comments
 (0)