summaryrefslogtreecommitdiffstats
path: root/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
diff options
context:
space:
mode:
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.java258
1 files changed, 182 insertions, 76 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 b06ccc5ec6..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.
@@ -334,29 +340,32 @@ public class QtActivityDelegate
if ((inputHints & (ImhDate | ImhTime)) != (ImhDate | ImhTime)) {
if ((inputHints & ImhDate) != 0)
inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_DATE;
- if ((inputHints & ImhTime) != 0)
+ else
inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_TIME;
} // else { TYPE_DATETIME_VARIATION_NORMAL(0) }
} else { // CLASS_TEXT
- if ((inputHints & (ImhEmailCharactersOnly | ImhUrlCharactersOnly)) != 0) {
- if ((inputHints & ImhUrlCharactersOnly) != 0) {
- inputType |= android.text.InputType.TYPE_TEXT_VARIATION_URI;
-
- if (enterKeyType == 0) // not explicitly overridden
- 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) {
+ if ((inputHints & ImhHiddenText) != 0) {
inputType |= android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
} else if ((inputHints & ImhSensitiveData) != 0 ||
((inputHints & ImhNoPredictiveText) != 0 &&
System.getenv("QT_ANDROID_ENABLE_WORKAROUND_TO_DISABLE_PREDICTIVE_TEXT") != null)) {
inputType |= android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
+ } else if ((inputHints & ImhUrlCharactersOnly) != 0) {
+ inputType |= android.text.InputType.TYPE_TEXT_VARIATION_URI;
+ if (enterKeyType == 0) // not explicitly overridden
+ imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
+ } else if ((inputHints & ImhEmailCharactersOnly) != 0) {
+ 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;
if ((inputHints & ImhUppercaseOnly) != 0) {
initialCapsMode |= android.text.TextUtils.CAP_MODE_CHARACTERS;
@@ -365,11 +374,6 @@ public class QtActivityDelegate
initialCapsMode |= android.text.TextUtils.CAP_MODE_SENTENCES;
inputType |= android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
}
-
- if ((inputHints & ImhNoPredictiveText) != 0 || (inputHints & ImhSensitiveData) != 0
- || (inputHints & ImhHiddenText) != 0) {
- inputType |= android.text.InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
- }
}
if (enterKeyType == 0 && (inputHints & ImhMultiLine) != 0)
@@ -492,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
@@ -564,6 +579,100 @@ public class QtActivityDelegate
}
}
+ private final DisplayManager.DisplayListener displayListener = new DisplayManager.DisplayListener()
+ {
+ @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)
{
/// check parameters integrity
@@ -573,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)
@@ -621,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);
@@ -662,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;
}
@@ -777,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);
@@ -803,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() {
@@ -817,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],
@@ -861,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)
@@ -882,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);
@@ -989,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);
@@ -1023,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
@@ -1194,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);
@@ -1226,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));