diff options
Diffstat (limited to 'src')
14 files changed, 342 insertions, 454 deletions
diff --git a/src/android/jar/CMakeLists.txt b/src/android/jar/CMakeLists.txt index 37f5e346ab..f600598c4d 100644 --- a/src/android/jar/CMakeLists.txt +++ b/src/android/jar/CMakeLists.txt @@ -12,7 +12,6 @@ set(java_sources src/org/qtproject/qt/android/QtActivityBase.java src/org/qtproject/qt/android/QtServiceBase.java src/org/qtproject/qt/android/QtActivityDelegate.java - src/org/qtproject/qt/android/QtServiceDelegate.java src/org/qtproject/qt/android/QtInputDelegate.java src/org/qtproject/qt/android/QtLoader.java src/org/qtproject/qt/android/QtActivityLoader.java diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java index f9db1ff24a..2e1a0228d3 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java @@ -173,7 +173,7 @@ public class QtActivityBase extends Activity super.onDestroy(); if (m_delegate.isQuitApp()) { QtNative.terminateQt(); - QtNative.setActivity(null, null); + QtNative.setActivity(null); QtNative.m_qtThread.exit(); System.exit(0); } @@ -325,6 +325,11 @@ public class QtActivityBase extends Activity QtNative.sendRequestPermissionsResult(requestCode, permissions, grantResults); } + public void hideSplashScreen(final int duration) + { + m_delegate.hideSplashScreen(duration); + } + QtActivityDelegate getActivityDelegate() { return m_delegate; diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java index 8a32b44c00..1d67117044 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java @@ -6,7 +6,6 @@ package org.qtproject.qt.android; import android.app.Activity; -import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; @@ -27,7 +26,6 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.Window; import android.view.WindowInsetsController; -import android.view.inputmethod.InputMethodManager; import android.view.ViewTreeObserver; import android.widget.ImageView; import android.widget.PopupMenu; @@ -56,34 +54,36 @@ public class QtActivityDelegate private QtAccessibilityDelegate m_accessibilityDelegate = null; private final QtDisplayManager m_displayManager = new QtDisplayManager(); - private QtInputDelegate.KeyboardVisibilityListener m_keyboardVisibilityListener = - new QtInputDelegate.KeyboardVisibilityListener() { - @Override - public void onKeyboardVisibilityChange() { - m_displayManager.updateFullScreen(m_activity); - } - }; - private final QtInputDelegate m_inputDelegate = new QtInputDelegate(m_keyboardVisibilityListener); + private QtInputDelegate m_inputDelegate = null; QtActivityDelegate(Activity activity) { m_activity = activity; - QtNative.setActivity(m_activity, this); + QtNative.setActivity(m_activity); setActionBarVisibility(false); + m_displayManager.registerDisplayListener(m_activity, m_layout); + + QtInputDelegate.KeyboardVisibilityListener keyboardVisibilityListener = + new QtInputDelegate.KeyboardVisibilityListener() { + @Override + public void onKeyboardVisibilityChange() { + m_displayManager.updateFullScreen(m_activity); + } + }; + m_inputDelegate = new QtInputDelegate(m_activity, keyboardVisibilityListener); + try { - m_inputDelegate.setSoftInputMode(m_activity.getPackageManager() - .getActivityInfo(m_activity.getComponentName(), 0).softInputMode); + PackageManager pm = m_activity.getPackageManager(); + ActivityInfo activityInfo = pm.getActivityInfo(m_activity.getComponentName(), 0); + m_inputDelegate.setSoftInputMode(activityInfo.softInputMode); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } - - m_displayManager.registerDisplayListener(m_activity, m_layout); } - QtDisplayManager displayManager() - { + QtDisplayManager displayManager() { return m_displayManager; } @@ -147,7 +147,7 @@ public class QtActivityDelegate try { // set new activity m_activity = activity; - QtNative.setActivity(m_activity, this); + QtNative.setActivity(m_activity); // update the new activity content view to old layout ViewGroup layoutParent = (ViewGroup) m_layout.getParent(); @@ -220,8 +220,6 @@ public class QtActivityDelegate e.printStackTrace(); } - m_inputDelegate.setEditText(new QtEditText(m_activity)); - m_inputDelegate.setInputMethodManager((InputMethodManager)m_activity.getSystemService(Context.INPUT_METHOD_SERVICE)); m_surfaces = new HashMap<Integer, QtSurface>(); m_nativeViews = new HashMap<Integer, View>(); m_activity.registerForContextMenu(m_layout); @@ -273,31 +271,40 @@ public class QtActivityDelegate public void hideSplashScreen(final int duration) { - if (m_splashScreen == null) - return; + QtNative.runAction(new Runnable() { + @Override + public void run() { + if (m_splashScreen == null) + return; - if (duration <= 0) { - m_layout.removeView(m_splashScreen); - m_splashScreen = null; - return; - } + if (duration <= 0) { + m_layout.removeView(m_splashScreen); + m_splashScreen = null; + return; + } - final Animation fadeOut = new AlphaAnimation(1, 0); - fadeOut.setInterpolator(new AccelerateInterpolator()); - fadeOut.setDuration(duration); + final Animation fadeOut = new AlphaAnimation(1, 0); + fadeOut.setInterpolator(new AccelerateInterpolator()); + fadeOut.setDuration(duration); - fadeOut.setAnimationListener(new Animation.AnimationListener() { - @Override - public void onAnimationEnd(Animation animation) { hideSplashScreen(0); } + fadeOut.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationEnd(Animation animation) { + hideSplashScreen(0); + } - @Override - public void onAnimationRepeat(Animation animation) {} + @Override + public void onAnimationRepeat(Animation animation) { + } - @Override - public void onAnimationStart(Animation animation) {} - }); + @Override + public void onAnimationStart(Animation animation) { + } + }); - m_splashScreen.startAnimation(fadeOut); + m_splashScreen.startAnimation(fadeOut); + } + }); } public void notifyLocationChange(int viewId) @@ -381,7 +388,22 @@ public class QtActivityDelegate public void resetOptionsMenu() { - m_activity.invalidateOptionsMenu(); + QtNative.runAction(new Runnable() { + @Override + public void run() { + m_activity.invalidateOptionsMenu(); + } + }); + } + + public void openOptionsMenu() + { + QtNative.runAction(new Runnable() { + @Override + public void run() { + m_activity.openOptionsMenu(); + } + }); } private boolean m_contextMenuVisible = false; @@ -395,31 +417,36 @@ public class QtActivityDelegate public void openContextMenu(final int x, final int y, final int w, final int h) { m_layout.postDelayed(new Runnable() { - @Override - public void run() { - m_layout.setLayoutParams(m_inputDelegate.getQtEditText(), new QtLayout.LayoutParams(w, h, x, y), false); - PopupMenu popup = new PopupMenu(m_activity, m_inputDelegate.getQtEditText()); - QtActivityDelegate.this.onCreatePopupMenu(popup.getMenu()); - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem menuItem) { - return m_activity.onContextItemSelected(menuItem); - } - }); - popup.setOnDismissListener(new PopupMenu.OnDismissListener() { - @Override - public void onDismiss(PopupMenu popupMenu) { - m_activity.onContextMenuClosed(popupMenu.getMenu()); - } - }); - popup.show(); - } - }, 100); + @Override + public void run() { + m_layout.setLayoutParams(m_inputDelegate.getQtEditText(), new QtLayout.LayoutParams(w, h, x, y), false); + PopupMenu popup = new PopupMenu(m_activity, m_inputDelegate.getQtEditText()); + QtActivityDelegate.this.onCreatePopupMenu(popup.getMenu()); + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + return m_activity.onContextItemSelected(menuItem); + } + }); + popup.setOnDismissListener(new PopupMenu.OnDismissListener() { + @Override + public void onDismiss(PopupMenu popupMenu) { + m_activity.onContextMenuClosed(popupMenu.getMenu()); + } + }); + popup.show(); + } + }, 100); } public void closeContextMenu() { - m_activity.closeContextMenu(); + QtNative.runAction(new Runnable() { + @Override + public void run() { + m_activity.closeContextMenu(); + } + }); } void setActionBarVisibility(boolean visible) @@ -433,96 +460,116 @@ public class QtActivityDelegate } public void insertNativeView(int id, View view, int x, int y, int w, int h) { - if (m_dummyView != null) { - m_layout.removeView(m_dummyView); - m_dummyView = null; - } + QtNative.runAction(new Runnable() { + @Override + public void run() { + if (m_dummyView != null) { + m_layout.removeView(m_dummyView); + m_dummyView = null; + } - if (m_nativeViews.containsKey(id)) - m_layout.removeView(m_nativeViews.remove(id)); + if (m_nativeViews.containsKey(id)) + m_layout.removeView(m_nativeViews.remove(id)); - if (w < 0 || h < 0) { - view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - } else { - view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y)); - } + if (w < 0 || h < 0) { + view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + } else { + view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y)); + } - view.setId(id); - m_layout.addView(view); - m_nativeViews.put(id, view); + view.setId(id); + m_layout.addView(view); + m_nativeViews.put(id, view); + } + }); } public void createSurface(int id, boolean onTop, int x, int y, int w, int h, int imageDepth) { - if (m_surfaces.size() == 0) { - TypedValue attr = new TypedValue(); - m_activity.getTheme().resolveAttribute(android.R.attr.windowBackground, attr, true); - if (attr.type >= TypedValue.TYPE_FIRST_COLOR_INT && attr.type <= TypedValue.TYPE_LAST_COLOR_INT) { - m_activity.getWindow().setBackgroundDrawable(new ColorDrawable(attr.data)); - } else { - m_activity.getWindow().setBackgroundDrawable(m_activity.getResources().getDrawable(attr.resourceId, m_activity.getTheme())); - } - if (m_dummyView != null) { - m_layout.removeView(m_dummyView); - m_dummyView = null; - } - } + QtNative.runAction(new Runnable() { + @Override + public void run() { + if (m_surfaces.size() == 0) { + TypedValue attr = new TypedValue(); + m_activity.getTheme().resolveAttribute(android.R.attr.windowBackground, attr, true); + if (attr.type >= TypedValue.TYPE_FIRST_COLOR_INT && attr.type <= TypedValue.TYPE_LAST_COLOR_INT) { + m_activity.getWindow().setBackgroundDrawable(new ColorDrawable(attr.data)); + } else { + m_activity.getWindow().setBackgroundDrawable(m_activity.getResources().getDrawable(attr.resourceId, m_activity.getTheme())); + } + if (m_dummyView != null) { + m_layout.removeView(m_dummyView); + m_dummyView = null; + } + } - if (m_surfaces.containsKey(id)) - m_layout.removeView(m_surfaces.remove(id)); + if (m_surfaces.containsKey(id)) + m_layout.removeView(m_surfaces.remove(id)); - QtSurface surface = new QtSurface(m_activity, id, onTop, imageDepth); - if (w < 0 || h < 0) { - surface.setLayoutParams( new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - } else { - surface.setLayoutParams( new QtLayout.LayoutParams(w, h, x, y)); - } + QtSurface surface = new QtSurface(m_activity, id, onTop, imageDepth); + if (w < 0 || h < 0) { + surface.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + } else { + surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y)); + } - // Native views are always inserted in the end of the stack (i.e., on top). - // All other views are stacked based on the order they are created. - final int surfaceCount = getSurfaceCount(); - m_layout.addView(surface, surfaceCount); + // Native views are always inserted in the end of the stack (i.e., on top). + // All other views are stacked based on the order they are created. + final int surfaceCount = getSurfaceCount(); + m_layout.addView(surface, surfaceCount); - m_surfaces.put(id, surface); - if (!m_splashScreenSticky) - hideSplashScreen(); + m_surfaces.put(id, surface); + if (!m_splashScreenSticky) + hideSplashScreen(); + } + }); } public void setSurfaceGeometry(int id, int x, int y, int w, int h) { - if (m_surfaces.containsKey(id)) { - QtSurface surface = m_surfaces.get(id); - surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y)); - } else if (m_nativeViews.containsKey(id)) { - View view = m_nativeViews.get(id); - view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y)); - } else { - Log.e(QtNative.QtTAG, "Surface " + id +" not found!"); - return; - } + QtNative.runAction(new Runnable() { + @Override + public void run() { + if (m_surfaces.containsKey(id)) { + QtSurface surface = m_surfaces.get(id); + surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y)); + } else if (m_nativeViews.containsKey(id)) { + View view = m_nativeViews.get(id); + view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y)); + } else { + Log.e(QtNative.QtTAG, "Surface " + id + " not found!"); + return; + } + } + }); } public void destroySurface(int id) { - View view = null; - - if (m_surfaces.containsKey(id)) { - view = m_surfaces.remove(id); - } else if (m_nativeViews.containsKey(id)) { - view = m_nativeViews.remove(id); - } else { - Log.e(QtNative.QtTAG, "Surface " + id +" not found!"); - } + QtNative.runAction(new Runnable() { + @Override + public void run() { + View view = null; + + if (m_surfaces.containsKey(id)) { + view = m_surfaces.remove(id); + } else if (m_nativeViews.containsKey(id)) { + view = m_nativeViews.remove(id); + } else { + Log.e(QtNative.QtTAG, "Surface " + id + " not found!"); + } - if (view == null) - return; + if (view == null) + return; - // Keep last frame in stack until it is replaced to get correct - // shutdown transition - if (m_surfaces.size() == 0 && m_nativeViews.size() == 0) { - m_dummyView = view; - } else { - m_layout.removeView(view); - } + // Keep last frame in stack until it is replaced to get correct + // shutdown transition + if (m_surfaces.size() == 0 && m_nativeViews.size() == 0) { + m_dummyView = view; + } else { + m_layout.removeView(view); + } + } + }); } public int getSurfaceCount() @@ -532,31 +579,41 @@ public class QtActivityDelegate public void bringChildToFront(int id) { - View view = m_surfaces.get(id); - if (view != null) { - final int surfaceCount = getSurfaceCount(); - if (surfaceCount > 0) - m_layout.moveChild(view, surfaceCount - 1); - return; - } + QtNative.runAction(new Runnable() { + @Override + public void run() { + View view = m_surfaces.get(id); + if (view != null) { + final int surfaceCount = getSurfaceCount(); + if (surfaceCount > 0) + m_layout.moveChild(view, surfaceCount - 1); + return; + } - view = m_nativeViews.get(id); - if (view != null) - m_layout.moveChild(view, -1); + view = m_nativeViews.get(id); + if (view != null) + m_layout.moveChild(view, -1); + } + }); } public void bringChildToBack(int id) { - View view = m_surfaces.get(id); - if (view != null) { - m_layout.moveChild(view, 0); - return; - } + QtNative.runAction(new Runnable() { + @Override + public void run() { + View view = m_surfaces.get(id); + if (view != null) { + m_layout.moveChild(view, 0); + return; + } - view = m_nativeViews.get(id); - if (view != null) { - final int index = getSurfaceCount(); - m_layout.moveChild(view, index); - } + view = m_nativeViews.get(id); + if (view != null) { + final int index = getSurfaceCount(); + m_layout.moveChild(view, index); + } + } + }); } } diff --git a/src/android/jar/src/org/qtproject/qt/android/QtEditText.java b/src/android/jar/src/org/qtproject/qt/android/QtEditText.java index b2df8959cc..a802abb2d4 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtEditText.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtEditText.java @@ -10,6 +10,8 @@ import android.view.View; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; +import org.qtproject.qt.android.QtInputConnection.QtInputConnectionListener; + public class QtEditText extends View { int m_initialCapsMode = 0; @@ -17,6 +19,13 @@ public class QtEditText extends View int m_inputType = InputType.TYPE_CLASS_TEXT; boolean m_optionsChanged = false; + private QtInputConnectionListener m_qtInputConnectionListener; + + public void setQtInputConnectionListener(QtInputConnectionListener listener) + { + m_qtInputConnectionListener = listener; + } + public void setImeOptions(int m_imeOptions) { if (m_imeOptions == this.m_imeOptions) @@ -56,7 +65,7 @@ public class QtEditText extends View outAttrs.imeOptions = m_imeOptions; outAttrs.initialCapsMode = m_initialCapsMode; outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_EXTRACT_UI; - return new QtInputConnection(this); + return new QtInputConnection(this, m_qtInputConnectionListener); } // // DEBUG CODE diff --git a/src/android/jar/src/org/qtproject/qt/android/QtInputConnection.java b/src/android/jar/src/org/qtproject/qt/android/QtInputConnection.java index bce476a94c..5b76a9f4d8 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtInputConnection.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtInputConnection.java @@ -51,31 +51,6 @@ class QtNativeInputConnection static native boolean updateCursorPosition(); } -class HideKeyboardRunnable implements Runnable { - private long m_hideTimeStamp = System.nanoTime(); - - @Override - public void run() { - // Check that the keyboard is really no longer there. - Activity activity = QtNative.activity(); - Rect r = new Rect(); - activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r); - - int screenHeight = 0; - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { - DisplayMetrics metrics = new DisplayMetrics(); - activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); - screenHeight = metrics.heightPixels; - } else { - final WindowMetrics maximumWindowMetrics = activity.getWindowManager().getMaximumWindowMetrics(); - screenHeight = maximumWindowMetrics.getBounds().height(); - } - final int kbHeight = screenHeight - r.bottom; - if (kbHeight < 100) - QtNative.activityDelegate().getInputDelegate().setKeyboardVisibility(false, m_hideTimeStamp); - } -} - public class QtInputConnection extends BaseInputConnection { private static final int ID_SELECT_ALL = android.R.id.selectAll; @@ -86,21 +61,52 @@ public class QtInputConnection extends BaseInputConnection private static final int ID_SWITCH_INPUT_METHOD = android.R.id.switchInputMethod; private static final int ID_ADD_TO_DICTIONARY = android.R.id.addToDictionary; + private final QtInputConnectionListener m_qtInputConnectionListener; + + class HideKeyboardRunnable implements Runnable { + @Override + public void run() { + // Check that the keyboard is really no longer there. + Activity activity = QtNative.activity(); + Rect r = new Rect(); + activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r); + + int screenHeight = 0; + if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { + DisplayMetrics metrics = new DisplayMetrics(); + activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); + screenHeight = metrics.heightPixels; + } else { + final WindowMetrics maximumWindowMetrics = activity.getWindowManager().getMaximumWindowMetrics(); + screenHeight = maximumWindowMetrics.getBounds().height(); + } + final int kbHeight = screenHeight - r.bottom; + if (kbHeight < 100) + m_qtInputConnectionListener.onHideKeyboardRunnableDone(false, System.nanoTime()); + } + } + + public interface QtInputConnectionListener { + void onSetClosing(boolean closing); + void onHideKeyboardRunnableDone(boolean visibility, long hideTimeStamp); + void onSendKeyEventDefaultCase(); + } + private QtEditText m_view = null; private void setClosing(boolean closing) { - if (closing) { + if (closing) m_view.postDelayed(new HideKeyboardRunnable(), 100); - } else { - QtNative.activityDelegate().getInputDelegate().setKeyboardVisibility(true, System.nanoTime()); - } + else + m_qtInputConnectionListener.onSetClosing(false); } - public QtInputConnection(QtEditText targetView) + public QtInputConnection(QtEditText targetView, QtInputConnectionListener listener) { super(targetView, true); m_view = targetView; + m_qtInputConnectionListener = listener; } @Override @@ -256,7 +262,7 @@ public class QtInputConnection extends BaseInputConnection break; default: - QtNative.activityDelegate().getInputDelegate().hideSoftwareKeyboard(); + m_qtInputConnectionListener.onSendKeyEventDefaultCase(); break; } } diff --git a/src/android/jar/src/org/qtproject/qt/android/QtInputDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtInputDelegate.java index ebdfd5339c..ee53dcd9ac 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtInputDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtInputDelegate.java @@ -4,6 +4,7 @@ package org.qtproject.qt.android; import android.app.Activity; +import android.content.Context; import android.graphics.Rect; import android.os.Bundle; import android.os.Handler; @@ -17,6 +18,8 @@ import android.view.MotionEvent; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; +import org.qtproject.qt.android.QtInputConnection.QtInputConnectionListener; + public class QtInputDelegate { // keyboard methods @@ -96,7 +99,7 @@ public class QtInputDelegate { private int m_lastChar = 0; private boolean m_backKeyPressedSent = false; - // Note: because of the circular call to updateFullScreen() from QtActivityDelegate, we need + // Note: because of the circular call to updateFullScreen() from the delegate, we need // a listener to be able to do that call from the delegate, because that's where that // logic lives public interface KeyboardVisibilityListener { @@ -105,9 +108,29 @@ public class QtInputDelegate { private final KeyboardVisibilityListener m_keyboardVisibilityListener; - QtInputDelegate(KeyboardVisibilityListener listener) + QtInputDelegate(Activity activity, KeyboardVisibilityListener listener) { this.m_keyboardVisibilityListener = listener; + m_editText = new QtEditText(activity); + m_imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + QtInputConnectionListener inputConnectionListener = new QtInputConnectionListener() { + @Override + public void onSetClosing(boolean closing) { + if (!closing) + setKeyboardVisibility(true, System.nanoTime()); + } + + @Override + public void onHideKeyboardRunnableDone(boolean visibility, long hideTimeStamp) { + setKeyboardVisibility(visibility, hideTimeStamp); + } + + @Override + public void onSendKeyEventDefaultCase() { + hideSoftwareKeyboard(); + } + }; + m_editText.setQtInputConnectionListener(inputConnectionListener); } public boolean isKeyboardVisible() @@ -131,16 +154,6 @@ public class QtInputDelegate { return m_editText; } - void setEditText(QtEditText editText) - { - m_editText = editText; - } - - void setInputMethodManager(InputMethodManager inputMethodManager) - { - m_imm = inputMethodManager; - } - void setEditPopupMenu(EditPopupMenu editPopupMenu) { m_editPopupMenu = editPopupMenu; diff --git a/src/android/jar/src/org/qtproject/qt/android/QtNative.java b/src/android/jar/src/org/qtproject/qt/android/QtNative.java index 4b812121cd..b8d5978536 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtNative.java @@ -54,11 +54,10 @@ import android.graphics.Rect; public class QtNative { + // TODO get rid of the delegation from QtNative, call directly the Activity in c++ private static Activity m_activity = null; private static boolean m_activityPaused = false; private static Service m_service = null; - private static QtActivityDelegate m_activityDelegate = null; - private static QtServiceDelegate m_serviceDelegate = null; public static Object m_mainActivityMutex = new Object(); // mutex used to synchronize runnable operations public static final String QtTAG = "Qt JAVA"; // string used for Log.x @@ -81,8 +80,8 @@ public class QtNative public static boolean isStarted() { - boolean hasActivity = m_activity != null && m_activityDelegate != null; - boolean hasService = m_service != null && m_serviceDelegate != null; + boolean hasActivity = m_activity != null; + boolean hasService = m_service != null; return m_started && (hasActivity || hasService); } @@ -111,21 +110,6 @@ public class QtNative } } - - public static QtActivityDelegate activityDelegate() - { - synchronized (m_mainActivityMutex) { - return m_activityDelegate; - } - } - - public static QtServiceDelegate serviceDelegate() - { - synchronized (m_mainActivityMutex) { - return m_serviceDelegate; - } - } - public static String[] getStringArray(String joinedString) { return joinedString.split(","); @@ -204,19 +188,17 @@ public class QtNative return m_qtThread; } - public static void setActivity(Activity qtMainActivity, QtActivityDelegate qtActivityDelegate) + public static void setActivity(Activity qtMainActivity) { synchronized (m_mainActivityMutex) { m_activity = qtMainActivity; - m_activityDelegate = qtActivityDelegate; } } - public static void setService(Service qtMainService, QtServiceDelegate qtServiceDelegate) + public static void setService(Service qtMainService) { synchronized (m_mainActivityMutex) { m_service = qtMainService; - m_serviceDelegate = qtServiceDelegate; } } @@ -349,72 +331,6 @@ public class QtNative return perm; } - // TODO get rid of the delegation from QtNative, call directly the Activity in c++ - private static void setSystemUiVisibility(final int systemUiVisibility) - { - runAction(new Runnable() { - @Override - public void run() { - if (m_activityDelegate != null) { - m_activityDelegate.setSystemUiVisibility(systemUiVisibility); - } - updateWindow(); - } - }); - } - - public static void notifyQtAndroidPluginRunning(final boolean running) - { - if (m_activityDelegate != null) - m_activityDelegate.notifyQtAndroidPluginRunning(running); - } - - - - private static void openContextMenu(final int x, final int y, final int w, final int h) - { - runAction(new Runnable() { - @Override - public void run() { - if (m_activityDelegate != null) - m_activityDelegate.openContextMenu(x, y, w, h); - } - }); - } - - private static void closeContextMenu() - { - runAction(new Runnable() { - @Override - public void run() { - if (m_activityDelegate != null) - m_activityDelegate.closeContextMenu(); - } - }); - } - - private static void resetOptionsMenu() - { - runAction(new Runnable() { - @Override - public void run() { - if (m_activityDelegate != null) - m_activityDelegate.resetOptionsMenu(); - } - }); - } - - private static void openOptionsMenu() - { - runAction(new Runnable() { - @Override - public void run() { - if (m_activity != null) - m_activity.openOptionsMenu(); - } - }); - } - private static byte[][] getSSLCertificates() { ArrayList<byte[]> certificateList = new ArrayList<byte[]>(); @@ -442,83 +358,6 @@ public class QtNative return certificateArray; } - private static void createSurface(final int id, final boolean onTop, final int x, final int y, final int w, final int h, final int imageDepth) - { - runAction(new Runnable() { - @Override - public void run() { - if (m_activityDelegate != null) - m_activityDelegate.createSurface(id, onTop, x, y, w, h, imageDepth); - } - }); - } - - private static void insertNativeView(final int id, final View view, final int x, final int y, final int w, final int h) - { - runAction(new Runnable() { - @Override - public void run() { - if (m_activityDelegate != null) - m_activityDelegate.insertNativeView(id, view, x, y, w, h); - } - }); - } - - private static void setSurfaceGeometry(final int id, final int x, final int y, final int w, final int h) - { - runAction(new Runnable() { - @Override - public void run() { - if (m_activityDelegate != null) - m_activityDelegate.setSurfaceGeometry(id, x, y, w, h); - } - }); - } - - private static void bringChildToFront(final int id) - { - runAction(new Runnable() { - @Override - public void run() { - if (m_activityDelegate != null) - m_activityDelegate.bringChildToFront(id); - } - }); - } - - private static void bringChildToBack(final int id) - { - runAction(new Runnable() { - @Override - public void run() { - if (m_activityDelegate != null) - m_activityDelegate.bringChildToBack(id); - } - }); - } - - private static void destroySurface(final int id) - { - runAction(new Runnable() { - @Override - public void run() { - if (m_activityDelegate != null) - m_activityDelegate.destroySurface(id); - } - }); - } - - private static void hideSplashScreen(final int duration) - { - runAction(new Runnable() { - @Override - public void run() { - if (m_activityDelegate != null) - m_activityDelegate.hideSplashScreen(duration); - } - }); - } - private static String[] listAssetContent(android.content.res.AssetManager asset, String path) { String [] list; ArrayList<String> res = new ArrayList<String>(); diff --git a/src/android/jar/src/org/qtproject/qt/android/QtServiceBase.java b/src/android/jar/src/org/qtproject/qt/android/QtServiceBase.java index 268a53044f..51eba48e6b 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtServiceBase.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtServiceBase.java @@ -9,15 +9,11 @@ import android.os.IBinder; import android.util.Log; public class QtServiceBase extends Service { - private QtServiceDelegate m_delegate; - @Override public void onCreate() { super.onCreate(); - m_delegate = new QtServiceDelegate(this); - // the application has already started, do not reload everything again if (QtNative.isStarted()) { Log.w(QtNative.QtTAG, @@ -38,7 +34,7 @@ public class QtServiceBase extends Service { super.onDestroy(); QtNative.quitQtCoreApplication(); QtNative.terminateQt(); - QtNative.setService(null, null); + QtNative.setService(null); QtNative.m_qtThread.exit(); System.exit(0); } @@ -49,9 +45,4 @@ public class QtServiceBase extends Service { return QtNative.onBind(intent); } } - - QtServiceDelegate getServiceDelegate() - { - return m_delegate; - } } diff --git a/src/android/jar/src/org/qtproject/qt/android/QtServiceDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtServiceDelegate.java deleted file mode 100644 index 9791bf78fc..0000000000 --- a/src/android/jar/src/org/qtproject/qt/android/QtServiceDelegate.java +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2016 BogDan Vatra <bogdan@kde.org> -// Copyright (C) 2023 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -package org.qtproject.qt.android; - -import android.app.Service; - -public class QtServiceDelegate -{ - private Service m_service = null; - - QtServiceDelegate(Service service) - { - m_service = service; - - // Set native context - QtNative.setService(m_service, this); - } -} diff --git a/src/corelib/platform/android/qandroidnativeinterface.cpp b/src/corelib/platform/android/qandroidnativeinterface.cpp index 3632c7fad4..e9a5957895 100644 --- a/src/corelib/platform/android/qandroidnativeinterface.cpp +++ b/src/corelib/platform/android/qandroidnativeinterface.cpp @@ -94,8 +94,7 @@ int QNativeInterface::QAndroidApplication::sdkVersion() */ void QNativeInterface::QAndroidApplication::hideSplashScreen(int duration) { - QJniObject::callStaticMethod<void>("org/qtproject/qt/android/QtNative", - "hideSplashScreen", "(I)V", duration); + QtAndroidPrivate::activity().callMethod<void>("hideSplashScreen", duration); } /*! diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 9f44a2ffe0..2cbd35e019 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -45,9 +45,6 @@ static jmethodID m_loadClassMethodID = nullptr; static AAssetManager *m_assetManager = nullptr; static jobject m_assets = nullptr; static jobject m_resourcesObj = nullptr; -static jmethodID m_createSurfaceMethodID = nullptr; -static jmethodID m_setSurfaceGeometryMethodID = nullptr; -static jmethodID m_destroySurfaceMethodID = nullptr; static QtJniTypes::QtActivityDelegate m_activityDelegate = nullptr; static QtJniTypes::QtInputDelegate m_inputDelegate = nullptr; @@ -165,7 +162,7 @@ namespace QtAndroid // TODO move calls from here to where they logically belong void setSystemUiVisibility(SystemUiVisibility uiVisibility) { - QJniObject::callStaticMethod<void>(m_applicationClass, "setSystemUiVisibility", "(I)V", jint(uiVisibility)); + qtActivityDelegate().callMethod<void>("setSystemUiVisibility", jint(uiVisibility)); } // FIXME: avoid direct access to QtActivityDelegate @@ -218,7 +215,7 @@ namespace QtAndroid void notifyQtAndroidPluginRunning(bool running) { - QJniObject::callStaticMethod<void>(m_applicationClass, "notifyQtAndroidPluginRunning","(Z)V", running); + qtActivityDelegate().callMethod<void>("notifyQtAndroidPluginRunning", running); } jobject createBitmap(QImage img, JNIEnv *env) @@ -338,12 +335,8 @@ namespace QtAndroid w = std::max(geometry.width(), 1); h = std::max(geometry.height(), 1); } - env->CallStaticVoidMethod(m_applicationClass, - m_createSurfaceMethodID, - surfaceId, - jboolean(onTop), - x, y, w, h, - imageDepth); + qtActivityDelegate().callMethod<void>("createSurface", surfaceId, jboolean(onTop), + x, y, w, h, imageDepth); return surfaceId; } @@ -358,9 +351,7 @@ namespace QtAndroid if (!geometry.isNull()) geometry.getRect(&x, &y, &w, &h); - QJniObject::callStaticMethod<void>(m_applicationClass, - "insertNativeView", - "(ILandroid/view/View;IIII)V", + qtActivityDelegate().callMethod<void>("insertNativeView", surfaceId, view, x, @@ -395,10 +386,7 @@ namespace QtAndroid w = geometry.width(); h = geometry.height(); } - env->CallStaticVoidMethod(m_applicationClass, - m_setSurfaceGeometryMethodID, - surfaceId, - x, y, w, h); + qtActivityDelegate().callMethod<void>("setSurfaceGeometry", surfaceId, x, y, w, h); } @@ -414,11 +402,7 @@ namespace QtAndroid m_surfaces.erase(it); } - QJniEnvironment env; - if (env.jniEnv()) - env->CallStaticVoidMethod(m_applicationClass, - m_destroySurfaceMethodID, - surfaceId); + qtActivityDelegate().callMethod<void>("destroySurface", surfaceId); } void bringChildToFront(int surfaceId) @@ -426,10 +410,7 @@ namespace QtAndroid if (surfaceId == -1) return; - QJniObject::callStaticMethod<void>(m_applicationClass, - "bringChildToFront", - "(I)V", - surfaceId); + qtActivityDelegate().callMethod<void>("bringChildToFront", surfaceId); } void bringChildToBack(int surfaceId) @@ -437,10 +418,7 @@ namespace QtAndroid if (surfaceId == -1) return; - QJniObject::callStaticMethod<void>(m_applicationClass, - "bringChildToBack", - "(I)V", - surfaceId); + qtActivityDelegate().callMethod<void>("bringChildToBack", surfaceId); } bool blockEventLoopsWhenSuspended() @@ -893,10 +871,6 @@ static bool registerNatives(QJniEnvironment &env) return JNI_FALSE; } - GET_AND_CHECK_STATIC_METHOD(m_createSurfaceMethodID, m_applicationClass, "createSurface", "(IZIIIII)V"); - GET_AND_CHECK_STATIC_METHOD(m_setSurfaceGeometryMethodID, m_applicationClass, "setSurfaceGeometry", "(IIIII)V"); - GET_AND_CHECK_STATIC_METHOD(m_destroySurfaceMethodID, m_applicationClass, "destroySurface", "(I)V"); - jmethodID methodID; GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "activity", "()Landroid/app/Activity;"); jobject contextObject = env->CallStaticObjectMethod(m_applicationClass, methodID); diff --git a/src/plugins/platforms/android/androidjnimenu.cpp b/src/plugins/platforms/android/androidjnimenu.cpp index a8af3feeb5..8bf37d1af2 100644 --- a/src/plugins/platforms/android/androidjnimenu.cpp +++ b/src/plugins/platforms/android/androidjnimenu.cpp @@ -31,8 +31,6 @@ namespace QtAndroidMenu static QWindow *activeTopLevelWindow = nullptr; Q_CONSTINIT static QRecursiveMutex menuBarMutex; - static jmethodID openContextMenuMethodID = 0; - static jmethodID clearMenuMethodID = 0; static jmethodID addMenuItemMethodID = 0; static int menuNoneValue = 0; @@ -46,29 +44,31 @@ namespace QtAndroidMenu void resetMenuBar() { - QJniObject::callStaticMethod<void>(applicationClass(), "resetOptionsMenu"); + qtActivityDelegate().callMethod<void>("resetOptionsMenu"); } void openOptionsMenu() { - QJniObject::callStaticMethod<void>(applicationClass(), "openOptionsMenu"); + qtActivityDelegate().callMethod<void>("openOptionsMenu"); } - void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env) + void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect) { QMutexLocker lock(&visibleMenuMutex); if (visibleMenu) pendingContextMenus.append(visibleMenu); visibleMenu = menu; menu->aboutToShow(); - env->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height()); + qtActivityDelegate().callMethod<void>("openContextMenu", + anchorRect.x(), anchorRect.y(), + anchorRect.width(), anchorRect.height()); } void hideContextMenu(QAndroidPlatformMenu *menu) { QMutexLocker lock(&visibleMenuMutex); if (visibleMenu == menu) { - QJniObject::callStaticMethod<void>(applicationClass(), "closeContextMenu"); + qtActivityDelegate().callMethod<void>("closeContextMenu"); pendingContextMenus.clear(); } else { pendingContextMenus.removeOne(menu); @@ -211,8 +211,10 @@ namespace QtAndroidMenu return order; } - static jboolean onPrepareOptionsMenu(JNIEnv *env, jobject /*thiz*/, jobject menu) + static jboolean onPrepareOptionsMenu(JNIEnv *env, jobject thiz, jobject menu) { + Q_UNUSED(thiz) + env->CallVoidMethod(menu, clearMenuMethodID); QMutexLocker lock(&menuBarMutex); if (!visibleMenuBar) @@ -249,8 +251,11 @@ namespace QtAndroidMenu return order ? JNI_TRUE : JNI_FALSE; } - static jboolean onOptionsItemSelected(JNIEnv *env, jobject /*thiz*/, jint menuId, jboolean checked) + static jboolean onOptionsItemSelected(JNIEnv *env, jobject thiz, jint menuId, jboolean checked) { + Q_UNUSED(env) + Q_UNUSED(thiz) + QMutexLocker lock(&menuBarMutex); if (!visibleMenuBar) return JNI_FALSE; @@ -260,7 +265,7 @@ namespace QtAndroidMenu QAndroidPlatformMenuItem *item = static_cast<QAndroidPlatformMenuItem *>(menus.front()->menuItemForId(menuId)); if (item) { if (item->menu()) { - showContextMenu(item->menu(), QRect(), env); + showContextMenu(item->menu(), QRect()); } else { if (item->isCheckable()) item->setChecked(checked); @@ -270,18 +275,23 @@ namespace QtAndroidMenu } else { QAndroidPlatformMenu *menu = static_cast<QAndroidPlatformMenu *>(visibleMenuBar->menuForId(menuId)); if (menu) - showContextMenu(menu, QRect(), env); + showContextMenu(menu, QRect()); } return JNI_TRUE; } - static void onOptionsMenuClosed(JNIEnv */*env*/, jobject /*thiz*/, jobject /*menu*/) + static void onOptionsMenuClosed(JNIEnv *env, jobject thiz, jobject menu) { + Q_UNUSED(env) + Q_UNUSED(thiz) + Q_UNUSED(menu) } - static void onCreateContextMenu(JNIEnv *env, jobject /*thiz*/, jobject menu) + static void onCreateContextMenu(JNIEnv *env, jobject thiz, jobject menu) { + Q_UNUSED(thiz) + env->CallVoidMethod(menu, clearMenuMethodID); QMutexLocker lock(&visibleMenuMutex); if (!visibleMenu) @@ -295,8 +305,9 @@ namespace QtAndroidMenu addAllMenuItemsToMenu(env, menu, visibleMenu); } - static void fillContextMenu(JNIEnv *env, jobject /*thiz*/, jobject menu) + static void fillContextMenu(JNIEnv *env, jobject thiz, jobject menu) { + Q_UNUSED(thiz) env->CallVoidMethod(menu, clearMenuMethodID); QMutexLocker lock(&visibleMenuMutex); if (!visibleMenu) @@ -305,13 +316,16 @@ namespace QtAndroidMenu addAllMenuItemsToMenu(env, menu, visibleMenu); } - static jboolean onContextItemSelected(JNIEnv *env, jobject /*thiz*/, jint menuId, jboolean checked) + static jboolean onContextItemSelected(JNIEnv *env, jobject thiz, jint menuId, jboolean checked) { + Q_UNUSED(env) + Q_UNUSED(thiz) + QMutexLocker lock(&visibleMenuMutex); QAndroidPlatformMenuItem * item = static_cast<QAndroidPlatformMenuItem *>(visibleMenu->menuItemForId(menuId)); if (item) { if (item->menu()) { - showContextMenu(item->menu(), QRect(), env); + showContextMenu(item->menu(), QRect()); } else { if (item->isCheckable()) item->setChecked(checked); @@ -328,8 +342,12 @@ namespace QtAndroidMenu return JNI_TRUE; } - static void onContextMenuClosed(JNIEnv *env, jobject /*thiz*/, jobject /*menu*/) + static void onContextMenuClosed(JNIEnv *env, jobject thiz, jobject menu) { + Q_UNUSED(env) + Q_UNUSED(thiz) + Q_UNUSED(menu) + QMutexLocker lock(&visibleMenuMutex); if (!visibleMenu) return; @@ -337,7 +355,7 @@ namespace QtAndroidMenu visibleMenu->aboutToHide(); visibleMenu = 0; if (!pendingContextMenus.empty()) - showContextMenu(pendingContextMenus.takeLast(), QRect(), env); + showContextMenu(pendingContextMenus.takeLast(), QRect()); } static JNINativeMethod methods[] = { @@ -387,8 +405,6 @@ namespace QtAndroidMenu return false; } - GET_AND_CHECK_STATIC_METHOD(openContextMenuMethodID, appClass, "openContextMenu", "(IIII)V"); - jclass clazz; FIND_AND_CHECK_CLASS("android/view/Menu"); GET_AND_CHECK_METHOD(clearMenuMethodID, clazz, "clear", "()V"); diff --git a/src/plugins/platforms/android/androidjnimenu.h b/src/plugins/platforms/android/androidjnimenu.h index 308f34867c..e10ad930d9 100644 --- a/src/plugins/platforms/android/androidjnimenu.h +++ b/src/plugins/platforms/android/androidjnimenu.h @@ -21,7 +21,7 @@ namespace QtAndroidMenu { // Menu support void openOptionsMenu(); - void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env); + void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect); void hideContextMenu(QAndroidPlatformMenu *menu); void syncMenu(QAndroidPlatformMenu *menu); void androidPlatformMenuDestroyed(QAndroidPlatformMenu *menu); diff --git a/src/plugins/platforms/android/qandroidplatformmenu.cpp b/src/plugins/platforms/android/qandroidplatformmenu.cpp index 4ddd6ea29a..e59fd2089d 100644 --- a/src/plugins/platforms/android/qandroidplatformmenu.cpp +++ b/src/plugins/platforms/android/qandroidplatformmenu.cpp @@ -119,7 +119,7 @@ void QAndroidPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &t Q_UNUSED(parentWindow); Q_UNUSED(item); setVisible(true); - QtAndroidMenu::showContextMenu(this, targetRect, QJniEnvironment().jniEnv()); + QtAndroidMenu::showContextMenu(this, targetRect); } QPlatformMenuItem *QAndroidPlatformMenu::menuItemForTag(quintptr tag) const |