Exemple #1
0
static bool Sys_Android_CheckBrowserAvailability( void )
{
	JNIEnv *env = Sys_Android_GetJNIEnv();
	jobject intent, list;
	jstring str;
	bool available;

	{
		jclass intentClass;
		jmethodID init, addCategory;
		jobject intentRef;

		intentClass = (*env)->FindClass( env, "android/content/Intent" );
		init = (*env)->GetMethodID( env, intentClass, "<init>", "(Ljava/lang/String;)V" );
		addCategory = (*env)->GetMethodID( env, intentClass, "addCategory", "(Ljava/lang/String;)Landroid/content/Intent;" );

		str = (*env)->NewStringUTF( env, "android.intent.action.MAIN" );
		intent = (*env)->NewObject( env, intentClass, init, str );
		(*env)->DeleteLocalRef( env, str );
		(*env)->DeleteLocalRef( env, intentClass );

		str = (*env)->NewStringUTF( env, "android.intent.category.APP_BROWSER" );
		intentRef = (*env)->CallObjectMethod( env, intent, addCategory, str );
		(*env)->DeleteLocalRef( env, str );
		(*env)->DeleteLocalRef( env, intentRef );
	}

	{
		jobject pm;
		jmethodID getPackageManager;
		jclass pmClass;
		jmethodID queryIntentActivities;

		getPackageManager = (*env)->GetMethodID( env, sys_android_activityClass,
			"getPackageManager", "()Landroid/content/pm/PackageManager;" );
		pm = (*env)->CallObjectMethod( env, sys_android_app->activity->clazz, getPackageManager );

		pmClass = (*env)->FindClass( env, "android/content/pm/PackageManager" );
		queryIntentActivities = (*env)->GetMethodID( env, pmClass,
			"queryIntentActivities", "(Landroid/content/Intent;I)Ljava/util/List;" );
		(*env)->DeleteLocalRef( env, pmClass );

		list = (*env)->CallObjectMethod( env, pm, queryIntentActivities, intent, 0x00010000 );
		(*env)->DeleteLocalRef( env, intent );
		(*env)->DeleteLocalRef( env, pm );
	}

	{
		jclass listClass;
		jmethodID isEmpty;

		listClass = (*env)->FindClass( env, "java/util/List" );
		isEmpty = (*env)->GetMethodID( env, listClass, "isEmpty", "()Z" );
		(*env)->DeleteLocalRef( env, listClass );
		available = ( (*env)->CallBooleanMethod( env, list, isEmpty ) == JNI_FALSE );
		(*env)->DeleteLocalRef( env, list );
	}

	return available;
}
Exemple #2
0
/*
* IN_Android_KeyEvent2UCS
*/
static wchar_t IN_Android_KeyEvent2UCS( const AInputEvent *event )
{
	JNIEnv *env = Sys_Android_GetJNIEnv();
	static jclass mapClass;
	static jmethodID load, get;
	jobject map;
	unsigned int ucs;

	if( !mapClass )
	{
		jclass mapClassRef;

		mapClassRef = (*env)->FindClass( env, "android/view/KeyCharacterMap" );
		mapClass = (*env)->NewGlobalRef( env, mapClassRef );
		load = (*env)->GetStaticMethodID( env, mapClass, "load", "(I)Landroid/view/KeyCharacterMap;" );
		get = (*env)->GetMethodID( env, mapClass, "get", "(II)I" );
		(*env)->DeleteLocalRef( env, mapClassRef );
	}

	map = (*env)->CallStaticObjectMethod( env, mapClass, load, AInputEvent_getDeviceId( event ) );
	ucs = (*env)->CallIntMethod( env, map, get, AKeyEvent_getKeyCode( event ), AKeyEvent_getMetaState( event ) );
	(*env)->DeleteLocalRef( env, map );

	return ucs;
}
Exemple #3
0
bool VID_GetDefaultMode( int *width, int *height )
{
	int i, modeWidth, modeHeight, lastWidth = 0, lastHeight = 0;
	static int maxWidth;

	if( !maxWidth )
	{
		JNIEnv *env = Sys_Android_GetJNIEnv();

		jstring name;
		jobject activityManager;
		jclass activityManagerClass;
		jmethodID getDeviceConfigurationInfo;

		jobject configurationInfo;
		jclass configurationInfoClass;
		jfieldID reqGlEsVersion;

		name = (*env)->NewStringUTF( env, "activity" );
		activityManager = (*env)->CallObjectMethod( env, sys_android_app->activity->clazz, sys_android_getSystemService, name );
		(*env)->DeleteLocalRef( env, name );
		activityManagerClass = (*env)->FindClass( env, "android/app/ActivityManager" );
		getDeviceConfigurationInfo = (*env)->GetMethodID( env, activityManagerClass,
			"getDeviceConfigurationInfo", "()Landroid/content/pm/ConfigurationInfo;" );
		(*env)->DeleteLocalRef( env, activityManagerClass );

		configurationInfo = (*env)->CallObjectMethod( env, activityManager, getDeviceConfigurationInfo );
		(*env)->DeleteLocalRef( env, activityManager );
		configurationInfoClass = (*env)->FindClass( env, "android/content/pm/ConfigurationInfo" );
		reqGlEsVersion = (*env)->GetFieldID( env, configurationInfoClass, "reqGlEsVersion", "I" );
		(*env)->DeleteLocalRef( env, configurationInfoClass );

		// Use full HD as the default on GPUs that support OpenGL ES 3.1, created in 2014 or later, such as NVIDIA Tegra K1.
		maxWidth = ( ( (*env)->GetIntField( env, configurationInfo, reqGlEsVersion ) >= 0x30001 ) ? 1920 : 1280 );
		(*env)->DeleteLocalRef( env, configurationInfo );
	}

	for( i = 0; VID_GetModeInfo( &modeWidth, &modeHeight, i ); i++ )
	{
		if( modeWidth > maxWidth )
			break;

		lastWidth = modeWidth;
		lastHeight = modeHeight;
	}

	assert( lastWidth && lastHeight ); // this function may be called only after vid mode initialization
	*width = lastWidth;
	*height = lastHeight;

	return true;
}
Exemple #4
0
void Sys_ReleaseWakeLock( void *wl )
{
	JNIEnv *env = Sys_Android_GetJNIEnv();
	static jmethodID release;

	if( !release )
	{
		jclass wlClass = (*env)->GetObjectClass( env, wl );
		release = (*env)->GetMethodID( env, wlClass, "release", "()V" );
		(*env)->DeleteLocalRef( env, wlClass );
	}

	(*env)->CallVoidMethod( env, wl, release );
}
Exemple #5
0
void Sys_OpenURLInBrowser( const char *url )
{
	JNIEnv *env = Sys_Android_GetJNIEnv();
	jobject uri, intent;
	jstring str;

	{
		jclass uriClass;
		jmethodID parse;

		uriClass = (*env)->FindClass( env, "android/net/Uri" );
		parse = (*env)->GetStaticMethodID( env, uriClass, "parse", "(Ljava/lang/String;)Landroid/net/Uri;" );
		str = (*env)->NewStringUTF( env, url );
		uri = (*env)->CallStaticObjectMethod( env, uriClass, parse, str );
		(*env)->DeleteLocalRef( env, str );
		(*env)->DeleteLocalRef( env, uriClass );
	}

	if( !uri )
		return;

	{
		jclass intentClass;
		jmethodID init, setData;
		jobject intentRef;

		intentClass = (*env)->FindClass( env, "android/content/Intent" );
		init = (*env)->GetMethodID( env, intentClass, "<init>", "(Ljava/lang/String;)V" );
		setData = (*env)->GetMethodID( env, intentClass, "setData", "(Landroid/net/Uri;)Landroid/content/Intent;" );

		str = (*env)->NewStringUTF( env, "android.intent.action.VIEW" );
		intent = (*env)->NewObject( env, intentClass, init, str );
		(*env)->DeleteLocalRef( env, str );
		(*env)->DeleteLocalRef( env, intentClass );

		intentRef = (*env)->CallObjectMethod( env, intent, setData, uri );
		(*env)->DeleteLocalRef( env, uri );
		(*env)->DeleteLocalRef( env, intentRef );
	}

	{
		jmethodID startActivity;

		startActivity = (*env)->GetMethodID( env, sys_android_activityClass, "startActivity", "(Landroid/content/Intent;)V" );
		(*env)->CallVoidMethod( env, sys_android_app->activity->clazz, startActivity, intent );
		(*env)->DeleteLocalRef( env, intent );
	}
}
Exemple #6
0
void *Sys_AcquireWakeLock( void )
{
	JNIEnv *env = Sys_Android_GetJNIEnv();
	static jmethodID acquire;

	if( !acquire )
	{
		jclass wlClass = (*env)->GetObjectClass( env, sys_android_wakeLock );
		acquire = (*env)->GetMethodID( env, wlClass, "acquire", "()V" );
		(*env)->DeleteLocalRef( env, wlClass );
	}

	(*env)->CallVoidMethod( env, sys_android_wakeLock, acquire );

	return sys_android_wakeLock;
}
Exemple #7
0
static void Sys_Android_ExecuteIntent( void )
{
	JNIEnv *env = Sys_Android_GetJNIEnv();
	static jmethodID getIntentCommand;
	jstring cmdJS;
	const char *cmd;

	if( !getIntentCommand )
		getIntentCommand = (*env)->GetMethodID( env, sys_android_activityClass, "getIntentCommand", "()Ljava/lang/String;" );

	cmdJS = (*env)->CallObjectMethod( env, sys_android_app->activity->clazz, getIntentCommand );
	if( !cmdJS )
		return;

	cmd = (*env)->GetStringUTFChars( env, cmdJS, NULL );
	Cbuf_AddText( cmd );
	(*env)->ReleaseStringUTFChars( env, cmdJS, cmd );
	(*env)->DeleteLocalRef( env, cmdJS );
}
Exemple #8
0
void Sys_ReleaseWakeLock( void *wl )
{
	JNIEnv *env = Sys_Android_GetJNIEnv();
	static jmethodID releaseWakeLock, releaseWifiLock;
	jclass wlClass;

	if( !releaseWakeLock )
	{
		wlClass = (*env)->GetObjectClass( env, sys_android_wakeLock );
		releaseWakeLock = (*env)->GetMethodID( env, wlClass, "release", "()V" );
		(*env)->DeleteLocalRef( env, wlClass );
	}
	if( !releaseWifiLock )
	{
		wlClass = (*env)->GetObjectClass( env, sys_android_wifiLock );
		releaseWifiLock = (*env)->GetMethodID( env, wlClass, "release", "()V" );
		(*env)->DeleteLocalRef( env, wlClass );
	}

	(*env)->CallVoidMethod( env, sys_android_wakeLock, releaseWakeLock );
	(*env)->CallVoidMethod( env, sys_android_wifiLock, releaseWifiLock );
}
Exemple #9
0
/*
* Sys_FS_AddFileToMedia
*/
void Sys_FS_AddFileToMedia( const char *filename )
{
#ifdef __ANDROID__
	ANativeActivity *activity = sys_android_app->activity;
	JNIEnv *env = Sys_Android_GetJNIEnv();
	char path[PATH_MAX];
	jobject file, uri, intent;

	if( !realpath( filename, path ) )
		return;

	{
		jclass fileClass;
		jmethodID ctor;
		jstring pathname;

		fileClass = (*env)->FindClass( env, "java/io/File" );
		ctor = (*env)->GetMethodID( env, fileClass, "<init>", "(Ljava/lang/String;)V" );
		pathname = (*env)->NewStringUTF( env, path );
		file = (*env)->NewObject( env, fileClass, ctor, pathname );
		(*env)->DeleteLocalRef( env, pathname );
		(*env)->DeleteLocalRef( env, fileClass );
	}

	if( !file )
		return;

	{
		jclass uriClass;
		jmethodID fromFile;

		uriClass = (*env)->FindClass( env, "android/net/Uri" );
		fromFile = (*env)->GetStaticMethodID( env, uriClass, "fromFile", "(Ljava/io/File;)Landroid/net/Uri;" );
		uri = (*env)->CallStaticObjectMethod( env, uriClass, fromFile, file );
		(*env)->DeleteLocalRef( env, file );
		(*env)->DeleteLocalRef( env, uriClass );
	}

	if( !uri )
		return;

	{
		jclass intentClass;
		jmethodID ctor, setData;
		jstring action;
		jobject intentRef;

		intentClass = (*env)->FindClass( env, "android/content/Intent" );

		ctor = (*env)->GetMethodID( env, intentClass, "<init>", "(Ljava/lang/String;)V" );
		action = (*env)->NewStringUTF( env, "android.intent.action.MEDIA_SCANNER_SCAN_FILE" );
		intent = (*env)->NewObject( env, intentClass, ctor, action );
		(*env)->DeleteLocalRef( env, action );

		setData = (*env)->GetMethodID( env, intentClass, "setData", "(Landroid/net/Uri;)Landroid/content/Intent;" );
		intentRef = (*env)->CallObjectMethod( env, intent, setData, uri );
		(*env)->DeleteLocalRef( env, uri );
		(*env)->DeleteLocalRef( env, intentRef );

		(*env)->DeleteLocalRef( env, intentClass );
	}

	{
		jmethodID sendBroadcast;

		sendBroadcast = (*env)->GetMethodID( env, sys_android_activityClass, "sendBroadcast", "(Landroid/content/Intent;)V" );
		(*env)->CallVoidMethod( env, activity->clazz, sendBroadcast, intent );
		(*env)->DeleteLocalRef( env, intent );
	}
#endif
}
Exemple #10
0
/*
* Sys_FS_GetMediaDirectory
*/
const char *Sys_FS_GetMediaDirectory( fs_mediatype_t type )
{
#ifdef __ANDROID__
	static char paths[FS_MEDIA_NUM_TYPES][PATH_MAX];
	static int pathsChecked;
	const char *publicDir;
	JNIEnv *env;
	jclass envClass;
	jmethodID getPublicDirectory;
	jstring js;
	jobject file;
	jclass fileClass;
	jmethodID getAbsolutePath;
	const char *pathUTF;

	if( paths[type][0] )
		return paths[type];

	if( pathsChecked & ( 1 << type ) )
		return NULL;

	switch( type )
	{
	case FS_MEDIA_IMAGES:
		publicDir = "Pictures";
		break;
	default:
		return NULL;
	}

	pathsChecked |= 1 << type;

	env = Sys_Android_GetJNIEnv();

	envClass = (*env)->FindClass( env, "android/os/Environment" );
	getPublicDirectory = (*env)->GetStaticMethodID( env, envClass, "getExternalStoragePublicDirectory",
		"(Ljava/lang/String;)Ljava/io/File;" );
	js = (*env)->NewStringUTF( env, publicDir );
	file = (*env)->CallStaticObjectMethod( env, envClass, getPublicDirectory, js );
	(*env)->DeleteLocalRef( env, js );
	(*env)->DeleteLocalRef( env, envClass );
	if( !file )
		return NULL;

	fileClass = (*env)->FindClass( env, "java/io/File" );
	getAbsolutePath = (*env)->GetMethodID( env, fileClass, "getAbsolutePath", "()Ljava/lang/String;" );
	js = (*env)->CallObjectMethod( env, file, getAbsolutePath );
	(*env)->DeleteLocalRef( env, file );
	(*env)->DeleteLocalRef( env, fileClass );

	pathUTF = (*env)->GetStringUTFChars( env, js, NULL );
	Q_strncpyz( paths[type], pathUTF, sizeof( paths[0] ) );
	(*env)->ReleaseStringUTFChars( env, js, pathUTF );
	(*env)->DeleteLocalRef( env, js );

	return paths[type];

#else
	return NULL;
#endif
}
Exemple #11
0
static void Sys_Android_Init( void )
{
	struct android_app *app = sys_android_app;
	JNIEnv *env;
	jobject activity = app->activity->clazz;

	// Set signal handlers.
	signal( SIGTERM, Sys_Android_SignalHandler );
	signal( SIGINT, Sys_Android_SignalHandler );

	// Set working directory to external data path.
	{
		char externalDataPath[PATH_MAX];
		Q_snprintfz( externalDataPath, sizeof( externalDataPath ), "%s/%d.%d",
			app->activity->externalDataPath, APP_VERSION_MAJOR, APP_VERSION_MINOR );
		FS_CreateAbsolutePath( externalDataPath );
		Sys_FS_CreateDirectory( externalDataPath );
		if( chdir( externalDataPath ) )
			Sys_Error( "Failed to change working directory" );
	}

	// Initialize JNI.
	if( pthread_key_create( &sys_android_jniEnvKey, Sys_Android_JNIEnvDestructor ) )
		Sys_Error( "Failed to create JNIEnv destructor" );
	env = Sys_Android_GetJNIEnv();

	// Activity class shortcut.
	{
		jclass activityClass = (*env)->GetObjectClass( env, activity );
		sys_android_activityClass = (*env)->NewGlobalRef( env, activityClass );
		sys_android_getSystemService = (*env)->GetMethodID( env, activityClass,
			"getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;" );
		(*env)->DeleteLocalRef( env, activityClass );
	}

	// Get package name.
	{
		jmethodID getPackageName;
		jstring packageNameJS;
		const char *packageNameUTF;

		getPackageName = (*env)->GetMethodID( env, sys_android_activityClass, "getPackageName", "()Ljava/lang/String;" );
		packageNameJS = (*env)->CallObjectMethod( env, activity, getPackageName );
		packageNameUTF = (*env)->GetStringUTFChars( env, packageNameJS, NULL );
		Q_strncpyz( sys_android_packageName, packageNameUTF, sizeof( sys_android_packageName ) );
		(*env)->ReleaseStringUTFChars( env, packageNameJS, packageNameUTF );
		(*env)->DeleteLocalRef( env, packageNameJS );
	}

	// Initialize the wake lock.
	{
		jstring name;
		jobject power;
		jclass powerClass;
		jmethodID newWakeLock;
		jstring tag;
		jobject wl;

		name = (*env)->NewStringUTF( env, "power" );
		power = (*env)->CallObjectMethod( env, activity, sys_android_getSystemService, name );
		(*env)->DeleteLocalRef( env, name );
		powerClass = (*env)->FindClass( env, "android/os/PowerManager" );
		newWakeLock = (*env)->GetMethodID( env, powerClass, "newWakeLock",
			"(ILjava/lang/String;)Landroid/os/PowerManager$WakeLock;" );
		(*env)->DeleteLocalRef( env, powerClass );
		tag = (*env)->NewStringUTF( env, "Qfusion" );
		wl = (*env)->CallObjectMethod( env, power, newWakeLock, 1, tag );
		(*env)->DeleteLocalRef( env, tag );
		(*env)->DeleteLocalRef( env, power );
		sys_android_wakeLock = (*env)->NewGlobalRef( env, wl );
		(*env)->DeleteLocalRef( env, wl );
	}

	// Set native app cmd handler to the actual one.
	app->onAppCmd = Sys_Android_OnAppCmd;

	// Check if browser links can be clicked.
	sys_android_browserAvailable = Sys_Android_CheckBrowserAvailability();
}
Exemple #12
0
static void Sys_Android_Init( void )
{
	struct android_app *app = sys_android_app;
	JNIEnv *env;
	jobject activity = app->activity->clazz;

	// Resolve the app's internal storage root directory.
	{
		char relativePath[PATH_MAX];
		Q_snprintfz( relativePath, sizeof( relativePath ), "%s/..", app->activity->internalDataPath );
		realpath( relativePath, sys_android_internalDataPath );
	}

	// Set working directory to external data path.
	{
		char externalDataPath[PATH_MAX];
		Q_snprintfz( externalDataPath, sizeof( externalDataPath ), "%s/%d.%d/", // The trailing slash is here to make it a directory path, not a file path
			app->activity->externalDataPath, APP_VERSION_MAJOR, APP_VERSION_MINOR );
		FS_CreateAbsolutePath( externalDataPath );
		if( chdir( externalDataPath ) )
			Sys_Error( "Failed to change working directory" );
	}

	// Initialize JNI.
	if( pthread_key_create( &sys_android_jniEnvKey, Sys_Android_JNIEnvDestructor ) )
		Sys_Error( "Failed to create JNIEnv destructor" );
	env = Sys_Android_GetJNIEnv();

	// Activity class shortcut.
	{
		jclass activityClass = (*env)->GetObjectClass( env, activity );
		sys_android_activityClass = (*env)->NewGlobalRef( env, activityClass );
		sys_android_getSystemService = (*env)->GetMethodID( env, activityClass,
			"getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;" );
		(*env)->DeleteLocalRef( env, activityClass );
	}

	// Get package name.
	{
		jmethodID getPackageName;
		jstring packageNameJS;
		const char *packageNameUTF;

		getPackageName = (*env)->GetMethodID( env, sys_android_activityClass, "getPackageName", "()Ljava/lang/String;" );
		packageNameJS = (*env)->CallObjectMethod( env, activity, getPackageName );
		packageNameUTF = (*env)->GetStringUTFChars( env, packageNameJS, NULL );
		Q_strncpyz( sys_android_packageName, packageNameUTF, sizeof( sys_android_packageName ) );
		(*env)->ReleaseStringUTFChars( env, packageNameJS, packageNameUTF );
		(*env)->DeleteLocalRef( env, packageNameJS );
	}

	// Initialize the wake lock.
	{
		jstring name;
		jobject power;
		jclass powerClass;
		jmethodID newWakeLock;
		jstring tag;
		jobject wakeLock;

		name = (*env)->NewStringUTF( env, "power" );
		power = (*env)->CallObjectMethod( env, activity, sys_android_getSystemService, name );
		(*env)->DeleteLocalRef( env, name );
		powerClass = (*env)->FindClass( env, "android/os/PowerManager" );
		newWakeLock = (*env)->GetMethodID( env, powerClass, "newWakeLock",
			"(ILjava/lang/String;)Landroid/os/PowerManager$WakeLock;" );
		(*env)->DeleteLocalRef( env, powerClass );
		tag = (*env)->NewStringUTF( env, "Qfusion" );
		wakeLock = (*env)->CallObjectMethod( env, power, newWakeLock, 1 /* PARTIAL_WAKE_LOCK */, tag );
		(*env)->DeleteLocalRef( env, tag );
		(*env)->DeleteLocalRef( env, power );
		sys_android_wakeLock = (*env)->NewGlobalRef( env, wakeLock );
		(*env)->DeleteLocalRef( env, wakeLock );
	}

	// Initialize the high-performance Wi-Fi lock.
	{
		jstring name;
		jobject wifi;
		jclass wifiClass;
		jmethodID createWifiLock;
		jstring tag;
		jobject wifiLock;

		name = (*env)->NewStringUTF( env, "wifi" );
		wifi = (*env)->CallObjectMethod( env, activity, sys_android_getSystemService, name );
		(*env)->DeleteLocalRef( env, name );
		wifiClass = (*env)->FindClass( env, "android/net/wifi/WifiManager" );
		createWifiLock = (*env)->GetMethodID( env, wifiClass, "createWifiLock",
			"(ILjava/lang/String;)Landroid/net/wifi/WifiManager$WifiLock;" );
		(*env)->DeleteLocalRef( env, wifiClass );
		tag = (*env)->NewStringUTF( env, "Qfusion" );
		wifiLock = (*env)->CallObjectMethod( env, wifi, createWifiLock, 3 /* WIFI_MODE_FULL_HIGH_PERF */, tag );
		(*env)->DeleteLocalRef( env, tag );
		(*env)->DeleteLocalRef( env, wifi );
		sys_android_wifiLock = (*env)->NewGlobalRef( env, wifiLock );
		(*env)->DeleteLocalRef( env, wifiLock );
	}

	// Set native app cmd handler to the actual one.
	app->onAppCmd = Sys_Android_OnAppCmd;

	// Check if browser links can be clicked.
	sys_android_browserAvailable = Sys_Android_CheckBrowserAvailability();
}