diff options
Diffstat (limited to 'src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java')
-rw-r--r-- | src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java | 435 |
1 files changed, 262 insertions, 173 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 7642bc38b5..f44465b4c5 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -50,6 +50,8 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.graphics.drawable.ColorDrawable; +import android.net.LocalServerSocket; +import android.net.LocalSocket; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -72,8 +74,11 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; +import java.io.BufferedReader; +import java.io.DataOutputStream; import java.io.File; import java.io.FileWriter; +import java.io.InputStreamReader; import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; @@ -265,30 +270,31 @@ public class QtActivityDelegate } if (Build.VERSION.SDK_INT > 10 && (inputHints & ImhHiddenText) != 0) - inputType |= 0x10; + inputType |= 0x10 /* TYPE_NUMBER_VARIATION_PASSWORD */; } else if ((inputHints & ImhDialableCharactersOnly) != 0) { inputType = android.text.InputType.TYPE_CLASS_PHONE; } else if ((inputHints & (ImhDate | ImhTime)) != 0) { inputType = android.text.InputType.TYPE_CLASS_DATETIME; - if ((inputHints & ImhDate) != 0) - inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_DATE; - if ((inputHints & ImhTime) != 0) - inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_TIME; + if ((inputHints & (ImhDate | ImhTime)) != (ImhDate | ImhTime)) { + if ((inputHints & ImhDate) != 0) + inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_DATE; + if ((inputHints & ImhTime) != 0) + inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_TIME; + } // else { TYPE_DATETIME_VARIATION_NORMAL(0) } } else { // CLASS_TEXT - if ((inputHints & ImhHiddenText) != 0) { + if ((inputHints & (ImhEmailCharactersOnly | ImhUrlCharactersOnly)) != 0) { + if ((inputHints & ImhUrlCharactersOnly) != 0) { + inputType |= android.text.InputType.TYPE_TEXT_VARIATION_URI; + imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO; + } else if ((inputHints & ImhEmailCharactersOnly) != 0) { + inputType |= android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS; + } + } else if ((inputHints & ImhHiddenText) != 0) { inputType |= android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD; - } else if ((inputHints & (ImhNoAutoUppercase | ImhNoPredictiveText | ImhSensitiveData)) != 0) { + } else if ((inputHints & ImhSensitiveData) != 0) { inputType |= android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD; } - if ((inputHints & ImhEmailCharactersOnly) != 0) - inputType |= android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS; - - if ((inputHints & ImhUrlCharactersOnly) != 0) { - inputType |= android.text.InputType.TYPE_TEXT_VARIATION_URI; - imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO; - } - if ((inputHints & ImhMultiLine) != 0) inputType |= android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE; @@ -300,8 +306,10 @@ public class QtActivityDelegate inputType |= android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES; } - if ((inputHints & ImhNoPredictiveText) != 0 || (inputHints & ImhSensitiveData) != 0) + if ((inputHints & ImhNoPredictiveText) != 0 || (inputHints & ImhSensitiveData) != 0 + || (inputHints & ImhHiddenText) != 0) { inputType |= android.text.InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS; + } } if ((inputHints & ImhMultiLine) != 0) @@ -485,6 +493,59 @@ public class QtActivityDelegate Log.i(QtNative.QtTAG, "DEBUGGER: " + msg); } + private class DebugWaitRunnable implements Runnable { + + public DebugWaitRunnable(String pingPongSocket) throws IOException { + socket = new LocalServerSocket(pingPongSocket); + } + + public boolean wasFailure; + private LocalServerSocket socket; + + public void run() { + final int napTime = 200; // milliseconds between file accesses + final int timeOut = 30000; // ms until we give up on ping and pong + final int maxAttempts = timeOut / napTime; + + try { + LocalSocket connectionFromClient = socket.accept(); + debugLog("Debug socket accepted"); + BufferedReader inFromClient = + new BufferedReader(new InputStreamReader(connectionFromClient.getInputStream())); + DataOutputStream outToClient = new DataOutputStream(connectionFromClient.getOutputStream()); + outToClient.writeBytes("" + android.os.Process.myPid()); + + for (int i = 0; i < maxAttempts; i++) { + String clientData = inFromClient.readLine(); + debugLog("Incoming socket " + clientData); + if (!clientData.isEmpty()) + break; + + if (connectionFromClient.isClosed()) { + wasFailure = true; + break; + } + Thread.sleep(napTime); + } + } catch (IOException ioEx) { + ioEx.printStackTrace(); + wasFailure = true; + Log.e(QtNative.QtTAG,"Can't start debugger" + ioEx.getMessage()); + } catch (InterruptedException interruptEx) { + wasFailure = true; + Log.e(QtNative.QtTAG,"Can't start debugger" + interruptEx.getMessage()); + } + } + + public void shutdown() throws IOException + { + wasFailure = true; + try { + socket.close(); + } catch (IOException ignored) { } + } + }; + public boolean startApplication() { // start application @@ -492,190 +553,218 @@ public class QtActivityDelegate // FIXME turn on debuggable check // if the applications is debuggable and it has a native debug request Bundle extras = m_activity.getIntent().getExtras(); - if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 - &&*/ extras != null - && extras.containsKey("native_debug") - && extras.getString("native_debug").equals("true")) { - try { - String packagePath = - m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(), - PackageManager.GET_CONFIGURATIONS).dataDir + "/"; - String gdbserverPath = - extras.containsKey("gdbserver_path") - ? extras.getString("gdbserver_path") - : packagePath+"lib/gdbserver "; - - String socket = - extras.containsKey("gdbserver_socket") - ? extras.getString("gdbserver_socket") - : "+debug-socket"; - - if (!(new File(gdbserverPath)).exists()) - gdbserverPath += ".so"; - - // start debugger - m_debuggerProcess = Runtime.getRuntime().exec(gdbserverPath - + socket - + " --attach " - + android.os.Process.myPid(), - null, - new File(packagePath)); - } catch (IOException ioe) { - Log.e(QtNative.QtTAG,"Can't start debugger" + ioe.getMessage()); - } catch (SecurityException se) { - Log.e(QtNative.QtTAG,"Can't start debugger" + se.getMessage()); - } catch (NameNotFoundException e) { - Log.e(QtNative.QtTAG,"Can't start debugger" + e.getMessage()); + if (extras != null) { + + if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 + &&*/ extras.containsKey("native_debug") + && extras.getString("native_debug").equals("true")) { + try { + String packagePath = + m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(), + PackageManager.GET_CONFIGURATIONS).dataDir + "/"; + String gdbserverPath = + extras.containsKey("gdbserver_path") + ? extras.getString("gdbserver_path") + : packagePath+"lib/gdbserver "; + + String socket = + extras.containsKey("gdbserver_socket") + ? extras.getString("gdbserver_socket") + : "+debug-socket"; + + if (!(new File(gdbserverPath)).exists()) + gdbserverPath += ".so"; + + // start debugger + m_debuggerProcess = Runtime.getRuntime().exec(gdbserverPath + + socket + + " --attach " + + android.os.Process.myPid(), + null, + new File(packagePath)); + } catch (IOException ioe) { + Log.e(QtNative.QtTAG,"Can't start debugger" + ioe.getMessage()); + } catch (SecurityException se) { + Log.e(QtNative.QtTAG,"Can't start debugger" + se.getMessage()); + } catch (NameNotFoundException e) { + Log.e(QtNative.QtTAG,"Can't start debugger" + e.getMessage()); + } } - } - if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 - &&*/ extras != null - && extras.containsKey("debug_ping") - && extras.getString("debug_ping").equals("true")) { - try { - debugLog("extra parameters: " + extras); - String packageName = m_activity.getPackageName(); - String pingFile = extras.getString("ping_file"); - String pongFile = extras.getString("pong_file"); - String gdbserverSocket = extras.getString("gdbserver_socket"); - String gdbserverCommand = extras.getString("gdbserver_command"); - boolean usePing = pingFile != null; - boolean usePong = pongFile != null; - boolean useSocket = gdbserverSocket != null; - int napTime = 200; // milliseconds between file accesses - int timeOut = 30000; // ms until we give up on ping and pong - int maxAttempts = timeOut / napTime; - - if (gdbserverSocket != null) { - debugLog("removing gdb socket " + gdbserverSocket); - new File(gdbserverSocket).delete(); - } - - if (usePing) { - debugLog("removing ping file " + pingFile); - File ping = new File(pingFile); - if (ping.exists()) { - if (!ping.delete()) - debugLog("ping file cannot be deleted"); + if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 + &&*/ extras.containsKey("debug_ping") + && extras.getString("debug_ping").equals("true")) { + try { + debugLog("extra parameters: " + extras); + String packageName = m_activity.getPackageName(); + String pingFile = extras.getString("ping_file"); + String pongFile = extras.getString("pong_file"); + String gdbserverSocket = extras.getString("gdbserver_socket"); + String gdbserverCommand = extras.getString("gdbserver_command"); + String pingSocket = extras.getString("ping_socket"); + boolean usePing = pingFile != null; + boolean usePong = pongFile != null; + boolean useSocket = gdbserverSocket != null; + boolean usePingSocket = pingSocket != null; + int napTime = 200; // milliseconds between file accesses + int timeOut = 30000; // ms until we give up on ping and pong + int maxAttempts = timeOut / napTime; + + if (gdbserverSocket != null) { + debugLog("removing gdb socket " + gdbserverSocket); + new File(gdbserverSocket).delete(); } - } - if (usePong) { - debugLog("removing pong file " + pongFile); - File pong = new File(pongFile); - if (pong.exists()) { - if (!pong.delete()) - debugLog("pong file cannot be deleted"); + if (usePing) { + debugLog("removing ping file " + pingFile); + File ping = new File(pingFile); + if (ping.exists()) { + if (!ping.delete()) + debugLog("ping file cannot be deleted"); + } } - } - debugLog("starting " + gdbserverCommand); - m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand); - debugLog("gdbserver started"); - - if (useSocket) { - int i; - for (i = 0; i < maxAttempts; ++i) { - debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i); - File file = new File(gdbserverSocket); - if (file.exists()) { - file.setReadable(true, false); - file.setWritable(true, false); - file.setExecutable(true, false); - break; + if (usePong) { + debugLog("removing pong file " + pongFile); + File pong = new File(pongFile); + if (pong.exists()) { + if (!pong.delete()) + debugLog("pong file cannot be deleted"); } - Thread.sleep(napTime); } - if (i == maxAttempts) { - debugLog("time out when waiting for socket"); - return false; + debugLog("starting " + gdbserverCommand); + m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand); + debugLog("gdbserver started"); + + if (useSocket) { + int i; + for (i = 0; i < maxAttempts; ++i) { + debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i); + File file = new File(gdbserverSocket); + if (file.exists()) { + file.setReadable(true, false); + file.setWritable(true, false); + file.setExecutable(true, false); + break; + } + Thread.sleep(napTime); + } + + if (i == maxAttempts) { + debugLog("time out when waiting for debug socket"); + return false; + } + + debugLog("socket ok"); + } else { + debugLog("socket not used"); } - debugLog("socket ok"); - } else { - debugLog("socket not used"); - } + if (usePingSocket) { + DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket); + Thread waitThread = new Thread(runnable); + waitThread.start(); - if (usePing) { - // Tell we are ready. - debugLog("writing ping at " + pingFile); - FileWriter writer = new FileWriter(pingFile); - writer.write("" + android.os.Process.myPid()); - writer.close(); - File file = new File(pingFile); - file.setReadable(true, false); - file.setWritable(true, false); - file.setExecutable(true, false); - debugLog("wrote ping"); - } else { - debugLog("ping not requested"); - } + int i; + for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) { + debugLog("Waiting for debug socket connect"); + debugLog("go to sleep"); + Thread.sleep(napTime); + } - // Wait until other side is ready. - if (usePong) { - int i; - for (i = 0; i < maxAttempts; ++i) { - debugLog("waiting for pong at " + pongFile + ", attempt " + i); - File file = new File(pongFile); - if (file.exists()) { - file.delete(); - break; + if (i == maxAttempts) { + debugLog("time out when waiting for ping socket"); + runnable.shutdown(); + return false; + } + + if (runnable.wasFailure) { + debugLog("Could not connect to debug client"); + return false; + } else { + debugLog("Got pid acknowledgment"); } - debugLog("go to sleep"); - Thread.sleep(napTime); } - debugLog("Removing pingFile " + pingFile); - new File(pingFile).delete(); - if (i == maxAttempts) { - debugLog("time out when waiting for pong file"); - return false; + if (usePing) { + // Tell we are ready. + debugLog("writing ping at " + pingFile); + FileWriter writer = new FileWriter(pingFile); + writer.write("" + android.os.Process.myPid()); + writer.close(); + File file = new File(pingFile); + file.setReadable(true, false); + file.setWritable(true, false); + file.setExecutable(true, false); + debugLog("wrote ping"); + } else { + debugLog("ping not requested"); } - debugLog("got pong " + pongFile); - } else { - debugLog("pong not requested"); - } + // Wait until other side is ready. + if (usePong) { + int i; + for (i = 0; i < maxAttempts; ++i) { + debugLog("waiting for pong at " + pongFile + ", attempt " + i); + File file = new File(pongFile); + if (file.exists()) { + file.delete(); + break; + } + debugLog("go to sleep"); + Thread.sleep(napTime); + } + debugLog("Removing pingFile " + pingFile); + new File(pingFile).delete(); + + if (i == maxAttempts) { + debugLog("time out when waiting for pong file"); + return false; + } - } catch (IOException ioe) { - Log.e(QtNative.QtTAG,"Can't start debugger" + ioe.getMessage()); - } catch (SecurityException se) { - Log.e(QtNative.QtTAG,"Can't start debugger" + se.getMessage()); + debugLog("got pong " + pongFile); + } else { + debugLog("pong not requested"); + } + + } catch (IOException ioe) { + Log.e(QtNative.QtTAG,"Can't start debugger" + ioe.getMessage()); + } catch (SecurityException se) { + Log.e(QtNative.QtTAG,"Can't start debugger" + se.getMessage()); + } } - } - if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 - &&*/ extras != null - && extras.containsKey("qml_debug") - && extras.getString("qml_debug").equals("true")) { - String qmljsdebugger; - if (extras.containsKey("qmljsdebugger")) { - qmljsdebugger = extras.getString("qmljsdebugger"); - qmljsdebugger.replaceAll("\\s", ""); // remove whitespace for security - } else { - qmljsdebugger = "port:3768"; + if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 + &&*/ extras.containsKey("qml_debug") + && extras.getString("qml_debug").equals("true")) { + String qmljsdebugger; + if (extras.containsKey("qmljsdebugger")) { + qmljsdebugger = extras.getString("qmljsdebugger"); + qmljsdebugger.replaceAll("\\s", ""); // remove whitespace for security + } else { + qmljsdebugger = "port:3768"; + } + m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger; } - m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger; - } - if (extras.containsKey("extraenvvars")) { - try { - m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8"); - } catch (Exception e) { - e.printStackTrace(); + if (extras.containsKey("extraenvvars")) { + try { + m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + } } - } - if (extras.containsKey("extraappparams")) { - try { - m_applicationParameters += "\t" + new String(Base64.decode(extras.getString("extraappparams"), Base64.DEFAULT), "UTF-8"); - } catch (Exception e) { - e.printStackTrace(); + if (extras.containsKey("extraappparams")) { + try { + m_applicationParameters += "\t" + new String(Base64.decode(extras.getString("extraappparams"), Base64.DEFAULT), "UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + } } - } + } // extras != null if (null == m_surfaces) onCreate(null); |