Android: Fix issue in loading multimedia Android plugin

Qt projects on Android were failing to correctly load the plugin lib.
The main reason is missing environment variables when the media
integration starts. To make sure that the variables are loaded, I have
change the setenv to be done in the java side instead of c++ side.

Fixes: QTBUG-100299
Pick-to: 6.3
Change-Id: Iba0b6af40574be2d88824ebdcfb1626335cecf09
Reviewed-by: Rami Potinkara <rami.potinkara@qt.io>
Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
bb10
Samuel Mira 2022-02-15 19:25:02 +02:00
parent 18f3867827
commit fef455999a
4 changed files with 69 additions and 49 deletions

View File

@ -127,7 +127,6 @@ public class QtActivityDelegate
public static final int SYSTEM_UI_VISIBILITY_FULLSCREEN = 1;
public static final int SYSTEM_UI_VISIBILITY_TRANSLUCENT = 2;
private static String m_environmentVariables = null;
private static String m_applicationParameters = null;
private int m_currentRotation = -1; // undefined
@ -483,7 +482,7 @@ public class QtActivityDelegate
});
}
String getAppIconSize(Activity a)
int getAppIconSize(Activity a)
{
int size = a.getResources().getDimensionPixelSize(android.R.dimen.app_icon_size);
if (size < 36 || size > 512) { // check size sanity
@ -496,7 +495,8 @@ public class QtActivityDelegate
if (size > 512)
size = 512;
}
return "\tQT_ANDROID_APP_ICON_SIZE=" + size;
return size;
}
public void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd)
@ -667,20 +667,16 @@ public class QtActivityDelegate
return false;
}
m_environmentVariables = loaderParams.getString(ENVIRONMENT_VARIABLES_KEY);
String additionalEnvironmentVariables = "QT_ANDROID_FONTS_MONOSPACE=Droid Sans Mono;Droid Sans;Droid Sans Fallback"
+ "\tQT_ANDROID_FONTS_SERIF=Droid Serif"
+ "\tHOME=" + m_activity.getFilesDir().getAbsolutePath()
+ "\tTMPDIR=" + m_activity.getFilesDir().getAbsolutePath();
additionalEnvironmentVariables += "\tQT_ANDROID_FONTS=Roboto;Droid Sans;Droid Sans Fallback";
additionalEnvironmentVariables += getAppIconSize(activity);
if (m_environmentVariables != null && m_environmentVariables.length() > 0)
m_environmentVariables = additionalEnvironmentVariables + "\t" + m_environmentVariables;
else
m_environmentVariables = additionalEnvironmentVariables;
QtNative.setEnvironmentVariables(loaderParams.getString(ENVIRONMENT_VARIABLES_KEY));
QtNative.setEnvironmentVariable("QT_ANDROID_FONTS_MONOSPACE",
"Droid Sans Mono;Droid Sans;Droid Sans Fallback");
QtNative.setEnvironmentVariable("QT_ANDROID_FONTS_SERIF", "Droid Serif");
QtNative.setEnvironmentVariable("HOME", m_activity.getFilesDir().getAbsolutePath());
QtNative.setEnvironmentVariable("TMPDIR", m_activity.getFilesDir().getAbsolutePath());
QtNative.setEnvironmentVariable("QT_ANDROID_FONTS",
"Roboto;Droid Sans;Droid Sans Fallback");
QtNative.setEnvironmentVariable("QT_ANDROID_APP_ICON_SIZE",
String.valueOf(getAppIconSize(activity)));
if (loaderParams.containsKey(APPLICATION_PARAMETERS_KEY))
m_applicationParameters = loaderParams.getString(APPLICATION_PARAMETERS_KEY);
@ -737,7 +733,9 @@ public class QtActivityDelegate
if (extras.containsKey("extraenvvars")) {
try {
m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8");
QtNative.setEnvironmentVariables(new String(
Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT),
"UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
@ -782,7 +780,7 @@ public class QtActivityDelegate
@Override
public void run() {
try {
QtNative.startApplication(m_applicationParameters, m_environmentVariables, m_mainLib);
QtNative.startApplication(m_applicationParameters, m_mainLib);
m_started = true;
} catch (Exception e) {
e.printStackTrace();

View File

@ -61,6 +61,7 @@ import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.system.Os;
import android.content.ClipboardManager;
import android.content.ClipData;
import android.content.ClipDescription;
@ -620,7 +621,7 @@ public class QtNative
});
}
public static boolean startApplication(String params, final String environment, String mainLib) throws Exception
public static boolean startApplication(String params, String mainLib) throws Exception
{
if (params == null)
params = "-platform\tandroid";
@ -634,7 +635,7 @@ public class QtNative
m_qtThread.run(new Runnable() {
@Override
public void run() {
res[0] = startQtAndroidPlugin(qtParams, environment);
res[0] = startQtAndroidPlugin(qtParams);
setDisplayMetrics(
m_displayMetricsScreenWidthPixels, m_displayMetricsScreenHeightPixels,
m_displayMetricsAvailableLeftPixels, m_displayMetricsAvailableTopPixels,
@ -693,7 +694,7 @@ public class QtNative
// application methods
public static native boolean startQtAndroidPlugin(String params, String env);
public static native boolean startQtAndroidPlugin(String params);
public static native void startQtApplication();
public static native void waitForServiceSetup();
public static native void quitQtCoreApplication();
@ -1367,6 +1368,40 @@ public class QtNative
return res.toArray(new String[res.size()]);
}
/**
*Sets a single environment variable
*
* returns true if the value was set, false otherwise.
* in case it cannot set value will log the exception
**/
public static void setEnvironmentVariable(String key, String value)
{
try {
android.system.Os.setenv(key, value, true);
} catch (Exception e) {
Log.e(QtNative.QtTAG, "Could not set environment variable:" + key + "=" + value);
e.printStackTrace();
}
}
/**
*Sets multiple environment variables
*
* Uses '\t' as divider between variables and '=' between key/value
* Ex: key1=val1\tkey2=val2\tkey3=val3
* Note: it assumed that the key cannot have '=' but the value can
**/
public static void setEnvironmentVariables(String environmentVariables)
{
for (String variable : environmentVariables.split("\t")) {
String[] keyvalue = variable.split("=", 2);
if (keyvalue.length < 2 || keyvalue[0].isEmpty())
continue;
setEnvironmentVariable(keyvalue[0], keyvalue[1]);
}
}
// screen methods
public static native void setDisplayMetrics(int screenWidthPixels, int screenHeightPixels,
int availableLeftPixels, int availableTopPixels,

View File

@ -101,7 +101,6 @@ public class QtServiceDelegate
private String m_mainLib = null;
private Service m_service = null;
private static String m_environmentVariables = null;
private static String m_applicationParameters = null;
public boolean loadApplication(Service service, ClassLoader classLoader, Bundle loaderParams)
@ -151,20 +150,19 @@ public class QtServiceDelegate
String nativeLibsDir = QtNativeLibrariesDir.nativeLibrariesDir(m_service);
QtNative.loadBundledLibraries(libraries, nativeLibsDir);
m_mainLib = loaderParams.getString(MAIN_LIBRARY_KEY);
m_environmentVariables = loaderParams.getString(ENVIRONMENT_VARIABLES_KEY);
String additionalEnvironmentVariables = "QT_ANDROID_FONTS_MONOSPACE=Droid Sans Mono;Droid Sans;Droid Sans Fallback"
+ "\tQT_ANDROID_FONTS_SERIF=Droid Serif"
+ "\tHOME=" + m_service.getFilesDir().getAbsolutePath()
+ "\tTMPDIR=" + m_service.getFilesDir().getAbsolutePath();
if (Build.VERSION.SDK_INT < 14)
additionalEnvironmentVariables += "\tQT_ANDROID_FONTS=Droid Sans;Droid Sans Fallback";
else
additionalEnvironmentVariables += "\tQT_ANDROID_FONTS=Roboto;Droid Sans;Droid Sans Fallback";
if (m_environmentVariables != null && m_environmentVariables.length() > 0)
m_environmentVariables = additionalEnvironmentVariables + "\t" + m_environmentVariables;
QtNative.setEnvironmentVariables(loaderParams.getString(ENVIRONMENT_VARIABLES_KEY));
QtNative.setEnvironmentVariable("QT_ANDROID_FONTS_MONOSPACE",
"Droid Sans Mono;Droid Sans;Droid Sans Fallback");
QtNative.setEnvironmentVariable("QT_ANDROID_FONTS_SERIF", "Droid Serif");
QtNative.setEnvironmentVariable("HOME", m_service.getFilesDir().getAbsolutePath());
QtNative.setEnvironmentVariable("TMPDIR", m_service.getFilesDir().getAbsolutePath());
if (Build.VERSION.SDK_INT < 14)
QtNative.setEnvironmentVariable("QT_ANDROID_FONTS", "Droid Sans;Droid Sans Fallback");
else
m_environmentVariables = additionalEnvironmentVariables;
QtNative.setEnvironmentVariable("QT_ANDROID_FONTS",
"Roboto;Droid Sans;Droid Sans Fallback");
if (loaderParams.containsKey(APPLICATION_PARAMETERS_KEY))
m_applicationParameters = loaderParams.getString(APPLICATION_PARAMETERS_KEY);
@ -180,7 +178,7 @@ public class QtServiceDelegate
// start application
try {
String nativeLibraryDir = QtNativeLibrariesDir.nativeLibrariesDir(m_service);
QtNative.startApplication(m_applicationParameters, m_environmentVariables, m_mainLib);
QtNative.startApplication(m_applicationParameters, m_mainLib);
return true;
} catch (Exception e) {
e.printStackTrace();

View File

@ -472,22 +472,12 @@ namespace QtAndroid
} // namespace QtAndroid
static jboolean startQtAndroidPlugin(JNIEnv *env, jobject /*object*/, jstring paramsString, jstring environmentString)
static jboolean startQtAndroidPlugin(JNIEnv *env, jobject /*object*/, jstring paramsString)
{
m_androidPlatformIntegration = nullptr;
m_androidAssetsFileEngineHandler = new AndroidAssetsFileEngineHandler();
m_androidContentFileEngineHandler = new AndroidContentFileEngineHandler();
m_mainLibraryHnd = nullptr;
{ // Set env. vars
const char *nativeString = env->GetStringUTFChars(environmentString, 0);
const QList<QByteArray> envVars = QByteArray(nativeString).split('\t');
env->ReleaseStringUTFChars(environmentString, nativeString);
for (const QByteArray &envVar : envVars) {
int pos = envVar.indexOf('=');
if (pos != -1 && ::setenv(envVar.left(pos), envVar.mid(pos + 1), 1) != 0)
qWarning() << "Can't set environment" << envVar;
}
}
const char *nativeString = env->GetStringUTFChars(paramsString, 0);
QByteArray string = nativeString;
@ -798,8 +788,7 @@ static jobject onBind(JNIEnv */*env*/, jclass /*cls*/, jobject intent)
}
static JNINativeMethod methods[] = {
{ "startQtAndroidPlugin", "(Ljava/lang/String;Ljava/lang/String;)Z",
(void *)startQtAndroidPlugin },
{ "startQtAndroidPlugin", "(Ljava/lang/String;)Z", (void *)startQtAndroidPlugin },
{ "startQtApplication", "()V", (void *)startQtApplication },
{ "quitQtAndroidPlugin", "()V", (void *)quitQtAndroidPlugin },
{ "quitQtCoreApplication", "()V", (void *)quitQtCoreApplication },