Merge pull request #81 from triplef/android-temp-dir

Added support for temp and caches dir on Android.
This commit is contained in:
Gregory Casamento 2019-11-25 04:09:56 -05:00 committed by GitHub
commit 69f7130fa7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 19 deletions

View file

@ -1950,9 +1950,7 @@ NSTemporaryDirectory(void)
int perm;
int owner;
BOOL flag;
#if !defined(_WIN32)
int uid;
#else
#if defined(_WIN32)
unichar buffer[1024];
if (GetTempPathW(1024, buffer))
@ -1960,6 +1958,20 @@ NSTemporaryDirectory(void)
baseTempDirName = [NSString stringWithCharacters: buffer
length: wcslen(buffer)];
}
#elif defined(__ANDROID__)
/*
* Use subfolder of cache directory as temp dir on Android, as there
* is no official temp dir prior to API level 26, and the cache dir
* is at least auto-purged by the system if disk space is needed.
* We also clean it up on launch in GSInitializeProcessAndroid().
*/
NSString *cacheDir = [[NSProcessInfo processInfo] androidCacheDir];
if (cacheDir)
{
baseTempDirName = [cacheDir stringByAppendingPathComponent: @"tmp"];
}
#else
int uid;
#endif
/*
@ -2004,10 +2016,31 @@ NSTemporaryDirectory(void)
if ([manager fileExistsAtPath: tempDirName isDirectory: &flag] == NO
|| flag == NO)
{
#ifdef __ANDROID__
/*
* Create our own temp dir on Android. We can disregard attributes
* since they are not supported.
*/
if ([manager createDirectoryAtPath: tempDirName
withIntermediateDirectories: YES
attributes: nil
error: NULL] == NO)
{
NSWarnFLog(@"Attempt to create temporary directory (%@)"
@" failed.", tempDirName);
return nil;
}
#else
NSWarnFLog(@"Temporary directory (%@) does not exist", tempDirName);
return nil;
#endif
}
// Mateu Batle: secure temporary directories don't work in MinGW
// Ivan Vucica: there are also problems with Cygwin
// probable cause: http://stackoverflow.com/q/9561759/39974
#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__ANDROID__)
/*
* Check that we are the directory owner, and that we, and nobody else,
* have access to it. If other people have access, try to create a secure
@ -2018,20 +2051,11 @@ NSTemporaryDirectory(void)
perm = [[attr objectForKey: NSFilePosixPermissions] intValue];
perm = perm & 0777;
// Mateu Batle: secure temporary directories don't work in MinGW
// Ivan Vucica: there are also problems with Cygwin
// probable cause: http://stackoverflow.com/q/9561759/39974
#if !defined(_WIN32) && !defined(__CYGWIN__)
#if defined(_WIN32)
uid = owner;
#else
#ifdef HAVE_GETEUID
uid = geteuid();
#else
uid = getuid();
#endif /* HAVE_GETEUID */
#endif
if ((perm != 0700 && perm != 0600) || owner != uid)
{
NSString *secure;
@ -2472,12 +2496,17 @@ L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\GNUstep",
case NSCachesDirectory:
{
#ifdef __ANDROID__
/* Use system-provided cache directory on Android */
ADD_PATH(NSUserDomainMask, [[NSProcessInfo processInfo] androidCacheDir], @"");
#else
/* Uff - at the moment the only place to put Caches seems to
* be Library. Unfortunately under GNU/Linux Library will
* end up in /usr/lib/GNUstep which could be mounted
* read-only!
*/
ADD_PATH(NSUserDomainMask, gnustepUserLibrary, @"Caches");
#endif
ADD_PATH(NSLocalDomainMask, gnustepLocalLibrary, @"Caches");
ADD_PATH(NSNetworkDomainMask, gnustepNetworkLibrary, @"Caches");
ADD_PATH(NSSystemDomainMask, gnustepSystemLibrary, @"Caches");

View file

@ -234,6 +234,7 @@ static NSMutableSet *mySet = nil;
#ifdef __ANDROID__
static jobject _androidContext = NULL;
static NSString *_androidFilesDir = nil;
static NSString *_androidCacheDir = nil;
#endif
/*************************************************************************
@ -1607,21 +1608,36 @@ GSInitializeProcessAndroid(JNIEnv *env, jobject context)
free(arg0);
// get File class and path method
jclass fileCls = (*env)->FindClass(env, "java/io/File");
jmethodID getAbsolutePathMethod = (*env)->GetMethodID(env, fileCls, "getAbsolutePath", "()Ljava/lang/String;");
// get Android files dir
jmethodID filesDirMethod = (*env)->GetMethodID(env, cls, "getFilesDir", "()Ljava/io/File;");
jobject filesDirObj = (*env)->CallObjectMethod(env, context, filesDirMethod);
jclass filesDirCls = (*env)->GetObjectClass(env, filesDirObj);
jmethodID getStoragePath = (*env)->GetMethodID(env, filesDirCls, "getAbsolutePath", "()Ljava/lang/String;");
jstring filesDirJava = (*env)->CallObjectMethod(env, filesDirObj, getStoragePath);
const jchar *unichars = (*env)->GetStringChars(env, filesDirJava, NULL);
jsize length = (*env)->GetStringLength(env, filesDirJava);
_androidFilesDir = [NSString stringWithCharacters:unichars length:length];
(*env)->ReleaseStringChars(env, filesDirJava, unichars);
jstring filesDirJava = (*env)->CallObjectMethod(env, filesDirObj, getAbsolutePathMethod);
const jchar *filesDirUnichars = (*env)->GetStringChars(env, filesDirJava, NULL);
jsize filesDirLength = (*env)->GetStringLength(env, filesDirJava);
_androidFilesDir = [NSString stringWithCharacters:filesDirUnichars length:filesDirLength];
(*env)->ReleaseStringChars(env, filesDirJava, filesDirUnichars);
// get Android cache dir
jmethodID cacheDirMethod = (*env)->GetMethodID(env, cls, "getCacheDir", "()Ljava/io/File;");
jobject cacheDirObj = (*env)->CallObjectMethod(env, context, cacheDirMethod);
jstring cacheDirJava = (*env)->CallObjectMethod(env, cacheDirObj, getAbsolutePathMethod);
const jchar *cacheDirUnichars = (*env)->GetStringChars(env, cacheDirJava, NULL);
jsize cacheDirLength = (*env)->GetStringLength(env, cacheDirJava);
_androidCacheDir = [NSString stringWithCharacters:cacheDirUnichars length:cacheDirLength];
(*env)->ReleaseStringChars(env, cacheDirJava, cacheDirUnichars);
// get asset manager and initialize NSBundle
jmethodID assetManagerMethod = (*env)->GetMethodID(env, cls, "getAssets", "()Landroid/content/res/AssetManager;");
jstring assetManagerJava = (*env)->CallObjectMethod(env, context, assetManagerMethod);
[NSBundle setJavaAssetManager:assetManagerJava withJNIEnv:env];
// clean up our NSTemporaryDirectory() if it exists
NSString *tempDirName = [_androidCacheDir stringByAppendingPathComponent: @"tmp"];
[[NSFileManager defaultManager] removeItemAtPath:tempDirName error:NULL];
}
#endif
@ -1667,6 +1683,11 @@ GSInitializeProcessAndroid(JNIEnv *env, jobject context)
{
return _androidFilesDir;
}
- (NSString *) androidCacheDir
{
return _androidCacheDir;
}
#endif
@end