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 | 243 |
1 files changed, 174 insertions, 69 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 a15a06a302..1218164d05 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org> -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com> ** Contact: https://www.qt.io/licensing/ ** @@ -69,6 +69,7 @@ import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; +import android.view.Display; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.Menu; @@ -154,6 +155,7 @@ public class QtActivityDelegate private CursorHandle m_leftSelectionHandle; private CursorHandle m_rightSelectionHandle; private EditPopupMenu m_editPopupMenu; + private boolean m_isPluginRunning = false; public void setFullScreen(boolean enterFullScreen) { @@ -190,6 +192,11 @@ public class QtActivityDelegate } } + public boolean isKeyboardVisible() + { + return m_keyboardIsVisible; + } + // input method hints - must be kept in sync with QTDIR/src/corelib/global/qnamespace.h private final int ImhHiddenText = 0x1; private final int ImhSensitiveData = 0x2; @@ -233,7 +240,6 @@ public class QtActivityDelegate private QtAccessibilityDelegate m_accessibilityDelegate = null; - public boolean setKeyboardVisibility(boolean visibility, long timeStamp) { if (m_showHideTimeStamp > timeStamp) @@ -243,7 +249,7 @@ public class QtActivityDelegate if (m_keyboardIsVisible == visibility) return false; m_keyboardIsVisible = visibility; - QtNative.keyboardVisibilityChanged(m_keyboardIsVisible); + QtNative.keyboardVisibilityUpdated(m_keyboardIsVisible); if (visibility == false) updateFullScreen(); // Hiding the keyboard clears the immersive mode, so we need to set it again. @@ -263,7 +269,7 @@ public class QtActivityDelegate }, 5); } - public void showSoftwareKeyboard(final int x, final int y, final int width, final int height, final int editorHeight, final int inputHints, final int enterKeyType) + public void showSoftwareKeyboard(final int x, final int y, final int width, final int height, final int inputHints, final int enterKeyType) { if (m_imm == null) return; @@ -285,7 +291,7 @@ public class QtActivityDelegate if (softInputIsHidden) return; } else { - if (editorHeight > visibleHeight) + if (height > visibleHeight) m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); else m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); @@ -352,8 +358,12 @@ public class QtActivityDelegate inputType |= android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS; } - if ((inputHints & ImhMultiLine) != 0) + if ((inputHints & ImhMultiLine) != 0) { inputType |= android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE; + // Clear imeOptions for Multi-Line Type + // User should be able to insert new line in such case + imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_DONE; + } if ((inputHints & (ImhNoPredictiveText | ImhSensitiveData | ImhHiddenText)) != 0) inputType |= android.text.InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS; @@ -402,12 +412,12 @@ public class QtActivityDelegate if (metrics.widthPixels > metrics.heightPixels) { // landscape if (m_landscapeKeyboardHeight != r.bottom) { m_landscapeKeyboardHeight = r.bottom; - showSoftwareKeyboard(x, y, width, height, editorHeight, inputHints, enterKeyType); + showSoftwareKeyboard(x, y, width, height, inputHints, enterKeyType); } } else { if (m_portraitKeyboardHeight != r.bottom) { m_portraitKeyboardHeight = r.bottom; - showSoftwareKeyboard(x, y, width, height, editorHeight, inputHints, enterKeyType); + showSoftwareKeyboard(x, y, width, height, inputHints, enterKeyType); } } } else { @@ -486,6 +496,17 @@ public class QtActivityDelegate private static final int CursorHandleShowSelection = 2; private static final int CursorHandleShowEdit = 0x100; + public int getSelectHandleWidth() + { + int width = 0; + if (m_leftSelectionHandle != null && m_rightSelectionHandle != null) + width = Math.max(m_leftSelectionHandle.width(), m_rightSelectionHandle.width()); + else if (m_cursorHandle != null) + width = m_cursorHandle.width(); + + return width; + } + /* called from the C++ code when the position of the cursor or selection handles needs to be adjusted. mode is one of QAndroidInputContext::CursorHandleShowMode @@ -558,12 +579,99 @@ public class QtActivityDelegate } } - public void updateInputItemRectangle(final int x, final int y, final int w, final int h) + private final DisplayManager.DisplayListener displayListener = new DisplayManager.DisplayListener() { - if (m_layout == null || m_editText == null || !m_keyboardIsVisible) - return; - m_layout.setLayoutParams(m_editText, new QtLayout.LayoutParams(w, h, x, y), true); - } + @Override + public void onDisplayAdded(int displayId) { } + + private boolean isSimilarRotation(int r1, int r2) + { + return (r1 == r2) + || (r1 == Surface.ROTATION_0 && r2 == Surface.ROTATION_180) + || (r1 == Surface.ROTATION_180 && r2 == Surface.ROTATION_0) + || (r1 == Surface.ROTATION_90 && r2 == Surface.ROTATION_270) + || (r1 == Surface.ROTATION_270 && r2 == Surface.ROTATION_90); + } + + @Override + public void onDisplayChanged(int displayId) + { + Display display = (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) + ? m_activity.getWindowManager().getDefaultDisplay() + : m_activity.getDisplay(); + m_currentRotation = display.getRotation(); + m_layout.setActivityDisplayRotation(m_currentRotation); + // Process orientation change only if it comes after the size + // change, or if the screen is rotated by 180 degrees. + // Otherwise it will be processed in QtLayout. + if (isSimilarRotation(m_currentRotation, m_layout.displayRotation())) + QtNative.handleOrientationChanged(m_currentRotation, m_nativeOrientation); + + float refreshRate = display.getRefreshRate(); + QtNative.handleRefreshRateChanged(refreshRate); + } + + @Override + public void onDisplayRemoved(int displayId) { } + }; + + public boolean updateActivity(Activity activity) + { + try { + // set new activity + loadActivity(activity); + + // update the new activity content view to old layout + ViewGroup layoutParent = (ViewGroup)m_layout.getParent(); + if (layoutParent != null) + layoutParent.removeView(m_layout); + + m_activity.setContentView(m_layout); + + // force c++ native activity object to update + return QtNative.updateNativeActivity(); + } catch (Exception e) { + Log.w(QtNative.QtTAG, "Failed to update the activity."); + e.printStackTrace(); + return false; + } + } + + private void loadActivity(Activity activity) + throws NoSuchMethodException, PackageManager.NameNotFoundException + { + m_activity = activity; + + QtNative.setActivity(m_activity, this); + setActionBarVisibility(false); + + Class<?> activityClass = m_activity.getClass(); + m_super_dispatchKeyEvent = + activityClass.getMethod("super_dispatchKeyEvent", KeyEvent.class); + m_super_onRestoreInstanceState = + activityClass.getMethod("super_onRestoreInstanceState", Bundle.class); + m_super_onRetainNonConfigurationInstance = + activityClass.getMethod("super_onRetainNonConfigurationInstance"); + m_super_onSaveInstanceState = + activityClass.getMethod("super_onSaveInstanceState", Bundle.class); + m_super_onKeyDown = + activityClass.getMethod("super_onKeyDown", Integer.TYPE, KeyEvent.class); + m_super_onKeyUp = + activityClass.getMethod("super_onKeyUp", Integer.TYPE, KeyEvent.class); + m_super_onConfigurationChanged = + activityClass.getMethod("super_onConfigurationChanged", Configuration.class); + m_super_onActivityResult = + activityClass.getMethod("super_onActivityResult", Integer.TYPE, Integer.TYPE, Intent.class); + m_super_onWindowFocusChanged = + activityClass.getMethod("super_onWindowFocusChanged", Boolean.TYPE); + m_super_dispatchGenericMotionEvent = + activityClass.getMethod("super_dispatchGenericMotionEvent", MotionEvent.class); + + m_softInputMode = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), 0).softInputMode; + + DisplayManager displayManager = (DisplayManager)m_activity.getSystemService(Context.DISPLAY_SERVICE); + displayManager.registerDisplayListener(displayListener, null); + } public boolean loadApplication(Activity activity, ClassLoader classLoader, Bundle loaderParams) { @@ -574,10 +682,14 @@ public class QtActivityDelegate return false; } - m_activity = activity; - setActionBarVisibility(false); - QtNative.setActivity(m_activity, this); - QtNative.setClassLoader(classLoader); + try { + loadActivity(activity); + QtNative.setClassLoader(classLoader); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + if (loaderParams.containsKey(STATIC_INIT_CLASSES_KEY)) { for (String className: Objects.requireNonNull(loaderParams.getStringArray(STATIC_INIT_CLASSES_KEY))) { if (className.length() == 0) @@ -622,22 +734,6 @@ public class QtActivityDelegate loaderParams.getBoolean(EXTRACT_STYLE_MINIMAL_KEY)); } - try { - m_super_dispatchKeyEvent = m_activity.getClass().getMethod("super_dispatchKeyEvent", KeyEvent.class); - m_super_onRestoreInstanceState = m_activity.getClass().getMethod("super_onRestoreInstanceState", Bundle.class); - m_super_onRetainNonConfigurationInstance = m_activity.getClass().getMethod("super_onRetainNonConfigurationInstance"); - m_super_onSaveInstanceState = m_activity.getClass().getMethod("super_onSaveInstanceState", Bundle.class); - m_super_onKeyDown = m_activity.getClass().getMethod("super_onKeyDown", Integer.TYPE, KeyEvent.class); - m_super_onKeyUp = m_activity.getClass().getMethod("super_onKeyUp", Integer.TYPE, KeyEvent.class); - m_super_onConfigurationChanged = m_activity.getClass().getMethod("super_onConfigurationChanged", Configuration.class); - m_super_onActivityResult = m_activity.getClass().getMethod("super_onActivityResult", Integer.TYPE, Integer.TYPE, Intent.class); - m_super_onWindowFocusChanged = m_activity.getClass().getMethod("super_onWindowFocusChanged", Boolean.TYPE); - m_super_dispatchGenericMotionEvent = m_activity.getClass().getMethod("super_dispatchGenericMotionEvent", MotionEvent.class); - } catch (Exception e) { - e.printStackTrace(); - return false; - } - int necessitasApiLevel = 1; if (loaderParams.containsKey(NECESSITAS_API_LEVEL_KEY)) necessitasApiLevel = loaderParams.getInt(NECESSITAS_API_LEVEL_KEY); @@ -663,33 +759,6 @@ public class QtActivityDelegate else m_applicationParameters = ""; - try { - m_softInputMode = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), 0).softInputMode; - } catch (Exception e) { - e.printStackTrace(); - } - - DisplayManager.DisplayListener displayListener = new DisplayManager.DisplayListener() { - @Override - public void onDisplayAdded(int displayId) { } - - @Override - public void onDisplayChanged(int displayId) { - m_currentRotation = m_activity.getWindowManager().getDefaultDisplay().getRotation(); - QtNative.handleOrientationChanged(m_currentRotation, m_nativeOrientation); - } - - @Override - public void onDisplayRemoved(int displayId) { } - }; - - try { - DisplayManager displayManager = (DisplayManager) m_activity.getSystemService(Context.DISPLAY_SERVICE); - displayManager.registerDisplayListener(displayListener, null); - } catch (Exception e) { - e.printStackTrace(); - } - m_mainLib = QtNative.loadMainLibrary(m_mainLib, nativeLibsDir); return m_mainLib != null; } @@ -778,7 +847,7 @@ public class QtActivityDelegate m_splashScreenSticky = info.metaData.containsKey("android.app.splash_screen_sticky") && info.metaData.getBoolean("android.app.splash_screen_sticky"); int id = info.metaData.getInt(splashScreenKey); m_splashScreen = new ImageView(m_activity); - m_splashScreen.setImageDrawable(m_activity.getResources().getDrawable(id)); + m_splashScreen.setImageDrawable(m_activity.getResources().getDrawable(id, m_activity.getTheme())); m_splashScreen.setScaleType(ImageView.ScaleType.FIT_XY); m_splashScreen.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); m_layout.addView(m_splashScreen); @@ -804,9 +873,15 @@ public class QtActivityDelegate else m_nativeOrientation = Configuration.ORIENTATION_PORTRAIT; + m_layout.setNativeOrientation(m_nativeOrientation); QtNative.handleOrientationChanged(rotation, m_nativeOrientation); m_currentRotation = rotation; + float refreshRate = (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) + ? m_activity.getWindowManager().getDefaultDisplay().getRefreshRate() + : m_activity.getDisplay().getRefreshRate(); + QtNative.handleRefreshRateChanged(refreshRate); + m_layout.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { @@ -818,6 +893,10 @@ public class QtActivityDelegate DisplayMetrics metrics = new DisplayMetrics(); m_activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); final int kbHeight = metrics.heightPixels - r.bottom; + if (kbHeight < 0) { + setKeyboardVisibility(false, System.nanoTime()); + return true; + } final int[] location = new int[2]; m_layout.getLocationOnScreen(location); QtNative.keyboardGeometryChanged(location[0], r.bottom - location[1], @@ -862,18 +941,18 @@ public class QtActivityDelegate m_splashScreen.startAnimation(fadeOut); } - public void notifyAccessibilityLocationChange() + public void notifyAccessibilityLocationChange(int viewId) { if (m_accessibilityDelegate == null) return; - m_accessibilityDelegate.notifyLocationChange(); + m_accessibilityDelegate.notifyLocationChange(viewId); } - public void notifyObjectHide(int viewId) + public void notifyObjectHide(int viewId, int parentId) { if (m_accessibilityDelegate == null) return; - m_accessibilityDelegate.notifyObjectHide(viewId); + m_accessibilityDelegate.notifyObjectHide(viewId, parentId); } public void notifyObjectFocus(int viewId) @@ -883,6 +962,25 @@ public class QtActivityDelegate m_accessibilityDelegate.notifyObjectFocus(viewId); } + public void notifyValueChanged(int viewId, String value) + { + if (m_accessibilityDelegate == null) + return; + m_accessibilityDelegate.notifyValueChanged(viewId, value); + } + + public void notifyScrolledEvent(int viewId) + { + if (m_accessibilityDelegate == null) + return; + m_accessibilityDelegate.notifyScrolledEvent(viewId); + } + + public void notifyQtAndroidPluginRunning(boolean running) + { + m_isPluginRunning = running; + } + public void initializeAccessibility() { m_accessibilityDelegate = new QtAccessibilityDelegate(m_activity, m_layout, this); @@ -990,7 +1088,7 @@ public class QtActivityDelegate public boolean onKeyDown(int keyCode, KeyEvent event) { - if (!m_started) + if (!m_started || !m_isPluginRunning) return false; m_metaState = MetaKeyKeyListener.handleKeyDown(m_metaState, keyCode, event); @@ -1024,7 +1122,7 @@ public class QtActivityDelegate public boolean onKeyUp(int keyCode, KeyEvent event) { - if (!m_started) + if (!m_started || !m_isPluginRunning) return false; if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP @@ -1195,7 +1293,7 @@ public class QtActivityDelegate 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.getWindow().setBackgroundDrawable(m_activity.getResources().getDrawable(attr.resourceId, m_activity.getTheme())); } if (m_dummyView != null) { m_layout.removeView(m_dummyView); @@ -1227,7 +1325,14 @@ public class QtActivityDelegate 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)); + QtLayout.LayoutParams params = new QtLayout.LayoutParams(w, h, x, y); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (m_activity.isInMultiWindowMode()) { + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.MATCH_PARENT; + } + } + surface.setLayoutParams(params); } else if (m_nativeViews.containsKey(id)) { View view = m_nativeViews.get(id); view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y)); |