Android: support lambda expressions in Java code

use -classpath instead of -bootclasspath param to allow
javac to use the default boot class path to support
building lambdas, pass the user Android class via -classpath.

Task-number: QTBUG-118077
Change-Id: I1ba8274d57e1bd528a1d5b7d779191e7f1412184
Reviewed-by: BogDan Vatra <bogdan@kdab.com>
Reviewed-by: Tinja Paavoseppä <tinja.paavoseppa@qt.io>
This commit is contained in:
Assam Boudjelthia 2023-11-16 20:18:49 +02:00
parent 323cf718f6
commit 64fe6d836c
10 changed files with 466 additions and 629 deletions

View File

@ -19,7 +19,8 @@ function(qt_internal_add_jar target)
set(javac_source_version "8")
endif()
set(CMAKE_JAVA_COMPILE_FLAGS -source "${javac_source_version}" -target "${javac_target_version}" -Xlint:unchecked -bootclasspath "${QT_ANDROID_JAR}")
set(CMAKE_JAVA_COMPILE_FLAGS -source "${javac_source_version}" -target "${javac_target_version}"
-Xlint:unchecked -classpath "${QT_ANDROID_JAR}")
add_jar(${ARGV})
foreach(f IN LISTS arg_SOURCES)

View File

@ -63,12 +63,7 @@ public class QtActivityDelegate
setActionBarVisibility(false);
QtInputDelegate.KeyboardVisibilityListener keyboardVisibilityListener =
new QtInputDelegate.KeyboardVisibilityListener() {
@Override
public void onKeyboardVisibilityChange() {
m_displayManager.updateFullScreen(m_activity);
}
};
() -> m_displayManager.updateFullScreen(m_activity);
m_inputDelegate = new QtInputDelegate(m_activity, keyboardVisibilityListener);
try {
@ -98,13 +93,10 @@ public class QtActivityDelegate
@UsedFromNativeCode
public void setSystemUiVisibility(int systemUiVisibility)
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
m_displayManager.setSystemUiVisibility(m_activity, systemUiVisibility);
m_layout.requestLayout();
QtNative.updateWindow();
}
});
}
@ -160,9 +152,7 @@ public class QtActivityDelegate
if (m_surfaces != null)
return;
Runnable startApplication = new Runnable() {
@Override
public void run() {
Runnable startApplication = () -> {
try {
QtNative.startApplication(appParams, mainLib);
m_started = true;
@ -170,7 +160,6 @@ public class QtActivityDelegate
e.printStackTrace();
m_activity.finish();
}
}
};
initMembers(startApplication);
@ -224,9 +213,7 @@ public class QtActivityDelegate
: m_activity.getDisplay().getRefreshRate();
QtDisplayManager.handleRefreshRateChanged(refreshRate);
m_layout.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
m_layout.getViewTreeObserver().addOnPreDrawListener(() -> {
if (!m_inputDelegate.isKeyboardVisible())
return true;
@ -244,7 +231,6 @@ public class QtActivityDelegate
QtInputDelegate.keyboardGeometryChanged(location[0], r.bottom - location[1],
r.width(), kbHeight);
return true;
}
});
m_inputDelegate.setEditPopupMenu(new EditPopupMenu(m_activity, m_layout));
}
@ -256,9 +242,7 @@ public class QtActivityDelegate
public void hideSplashScreen(final int duration)
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
if (m_splashScreen == null)
return;
@ -288,7 +272,6 @@ public class QtActivityDelegate
});
m_splashScreen.startAnimation(fadeOut);
}
});
}
@ -342,13 +325,8 @@ public class QtActivityDelegate
public void initializeAccessibility()
{
final QtActivityDelegate currentDelegate = this;
QtNative.runAction(new Runnable() {
@Override
public void run() {
m_accessibilityDelegate = new QtAccessibilityDelegate(m_activity, m_layout,
currentDelegate);
}
});
QtNative.runAction(() -> m_accessibilityDelegate = new QtAccessibilityDelegate(m_activity,
m_layout, currentDelegate));
}
void handleUiModeChange(int uiMode)
@ -381,23 +359,13 @@ public class QtActivityDelegate
@UsedFromNativeCode
public void resetOptionsMenu()
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
m_activity.invalidateOptionsMenu();
}
});
QtNative.runAction(() -> m_activity.invalidateOptionsMenu());
}
@UsedFromNativeCode
public void openOptionsMenu()
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
m_activity.openOptionsMenu();
}
});
QtNative.runAction(() -> m_activity.openOptionsMenu());
}
private boolean m_contextMenuVisible = false;
@ -411,38 +379,22 @@ public class QtActivityDelegate
@UsedFromNativeCode
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.postDelayed(() -> {
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.setOnMenuItemClickListener(menuItem ->
m_activity.onContextItemSelected(menuItem));
popup.setOnDismissListener(popupMenu ->
m_activity.onContextMenuClosed(popupMenu.getMenu()));
popup.show();
}
}, 100);
}
@UsedFromNativeCode
public void closeContextMenu()
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
m_activity.closeContextMenu();
}
});
QtNative.runAction(() -> m_activity.closeContextMenu());
}
void setActionBarVisibility(boolean visible)
@ -457,9 +409,7 @@ public class QtActivityDelegate
@UsedFromNativeCode
public void insertNativeView(int id, View view, int x, int y, int w, int h) {
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
if (m_dummyView != null) {
m_layout.removeView(m_dummyView);
m_dummyView = null;
@ -478,15 +428,12 @@ public class QtActivityDelegate
view.setId(id);
m_layout.addView(view);
m_nativeViews.put(id, view);
}
});
}
@UsedFromNativeCode
public void createSurface(int id, boolean onTop, int x, int y, int w, int h, int imageDepth) {
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
if (m_surfaces.size() == 0) {
TypedValue attr = new TypedValue();
m_activity.getTheme().resolveAttribute(android.R.attr.windowBackground, attr, true);
@ -520,15 +467,12 @@ public class QtActivityDelegate
m_surfaces.put(id, surface);
if (!m_splashScreenSticky)
hideSplashScreen();
}
});
}
@UsedFromNativeCode
public void setSurfaceGeometry(int id, int x, int y, int w, int h) {
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
if (m_surfaces.containsKey(id)) {
QtSurface surface = m_surfaces.get(id);
surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
@ -537,17 +481,13 @@ public class QtActivityDelegate
view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
} else {
Log.e(QtNative.QtTAG, "Surface " + id + " not found!");
return;
}
}
});
}
@UsedFromNativeCode
public void destroySurface(int id) {
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
View view = null;
if (m_surfaces.containsKey(id)) {
@ -568,7 +508,6 @@ public class QtActivityDelegate
} else {
m_layout.removeView(view);
}
}
});
}
@ -580,9 +519,7 @@ public class QtActivityDelegate
@UsedFromNativeCode
public void bringChildToFront(int id)
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
View view = m_surfaces.get(id);
if (view != null) {
final int surfaceCount = getSurfaceCount();
@ -594,16 +531,13 @@ public class QtActivityDelegate
view = m_nativeViews.get(id);
if (view != null)
m_layout.moveChild(view, -1);
}
});
}
@UsedFromNativeCode
public void bringChildToBack(int id)
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
View view = m_surfaces.get(id);
if (view != null) {
m_layout.moveChild(view, 0);
@ -615,7 +549,6 @@ public class QtActivityDelegate
final int index = getSurfaceCount();
m_layout.moveChild(view, index);
}
}
});
}
}

View File

@ -52,12 +52,7 @@ public class QtActivityLoader extends QtLoader {
"fatal_error_msg", "string", packageName);
errorDialog.setMessage(resources.getString(id));
errorDialog.setButton(Dialog.BUTTON_POSITIVE, resources.getString(android.R.string.ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
(dialog, which) -> finish());
errorDialog.show();
}

View File

@ -35,21 +35,14 @@ public class QtClipboardManager
{
if (context != null) {
final Semaphore semaphore = new Semaphore(0);
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
m_clipboardManager =
(ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
if (m_clipboardManager != null) {
m_clipboardManager.addPrimaryClipChangedListener(
new ClipboardManager.OnPrimaryClipChangedListener() {
public void onPrimaryClipChanged() {
onClipboardDataChanged(m_nativePointer);
}
});
() -> onClipboardDataChanged(m_nativePointer));
}
semaphore.release();
}
});
try {
semaphore.acquire();

View File

@ -188,12 +188,9 @@ public class QtInputDelegate {
{
if (m_imm == null)
return;
m_editText.postDelayed(new Runnable() {
@Override
public void run() {
m_editText.postDelayed(() -> {
m_imm.restartInput(m_editText);
m_editText.m_optionsChanged = false;
}
}, 5);
}
@ -201,9 +198,7 @@ public class QtInputDelegate {
final int x, final int y, final int width, final int height,
final int inputHints, final int enterKeyType)
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
if (m_imm == null)
return;
@ -217,9 +212,7 @@ public class QtInputDelegate {
layout.setLayoutParams(m_editText, layoutParams, false);
m_editText.requestFocus();
m_editText.postDelayed(new Runnable() {
@Override
public void run() {
m_editText.postDelayed(() -> {
m_imm.showSoftInput(m_editText, 0, new ResultReceiver(new Handler()) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
@ -245,9 +238,7 @@ public class QtInputDelegate {
m_imm.restartInput(m_editText);
m_editText.m_optionsChanged = false;
}
}
}, 15);
}
});
}
@ -392,9 +383,7 @@ public class QtInputDelegate {
private void probeForKeyboardHeight(QtLayout layout, Activity activity, int x, int y,
int width, int height, int inputHints, int enterKeyType)
{
layout.postDelayed(new Runnable() {
@Override
public void run() {
layout.postDelayed(() -> {
if (!m_keyboardIsVisible)
return;
DisplayMetrics metrics = new DisplayMetrics();
@ -421,16 +410,13 @@ public class QtInputDelegate {
if (m_probeKeyboardHeightDelayMs < 1000)
m_probeKeyboardHeightDelayMs *= 2;
}
}
}, m_probeKeyboardHeightDelayMs);
}
public void hideSoftwareKeyboard()
{
m_isKeyboardHidingAnimationOngoing = true;
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
if (m_imm == null)
return;
@ -450,7 +436,6 @@ public class QtInputDelegate {
}
}
});
}
});
}
@ -458,14 +443,11 @@ public class QtInputDelegate {
public void updateSelection(final int selStart, final int selEnd,
final int candidatesStart, final int candidatesEnd)
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
if (m_imm == null)
return;
m_imm.updateSelection(m_editText, selStart, selEnd, candidatesStart, candidatesEnd);
}
});
}
@ -490,13 +472,8 @@ public class QtInputDelegate {
int editX, int editY, int editButtons,
int x1, int y1, int x2, int y2, boolean rtl)
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
updateHandleImpl(activity, layout, mode, editX, editY, editButtons,
x1, y1, x2, y2, rtl);
}
});
QtNative.runAction(() -> updateHandleImpl(activity, layout, mode, editX, editY, editButtons,
x1, y1, x2, y2, rtl));
}
private void updateHandleImpl(Activity activity, QtLayout layout, int mode,

View File

@ -462,13 +462,10 @@ public abstract class QtLoader {
ArrayList<String> oneEntryArray = new ArrayList<>(Collections.singletonList(mainLibName));
String mainLibPath = getLibrariesFullPaths(oneEntryArray).get(0);
final boolean[] success = {true};
QtNative.getQtThread().run(new Runnable() {
@Override
public void run() {
QtNative.getQtThread().run(() -> {
m_mainLib = loadLibraryHelper(mainLibPath);
if (m_mainLib == null)
success[0] = false;
}
});
return success[0];
@ -488,9 +485,7 @@ public abstract class QtLoader {
ArrayList<String> fullPathLibs = getLibrariesFullPaths(libraries);
final boolean[] success = {true};
QtNative.getQtThread().run(new Runnable() {
@Override
public void run() {
QtNative.getQtThread().run(() -> {
for (int i = 0; i < fullPathLibs.size(); ++i) {
String libName = fullPathLibs.get(i);
if (loadLibraryHelper(libName) == null) {
@ -498,7 +493,6 @@ public abstract class QtLoader {
break;
}
}
}
});
return success[0];

View File

@ -159,9 +159,7 @@ public class QtMessageDialogHelper
public void show(long handler)
{
m_handler = handler;
m_activity.runOnUiThread( new Runnable() {
@Override
public void run() {
m_activity.runOnUiThread(() -> {
if (m_dialog != null && m_dialog.isShowing())
m_dialog.dismiss();
@ -170,12 +168,7 @@ public class QtMessageDialogHelper
if (m_title != null)
m_dialog.setTitle(m_title);
m_dialog.setOnCancelListener( new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
QtNativeDialogHelper.dialogResult(handler(), -1);
}
});
m_dialog.setOnCancelListener(dialogInterface -> QtNativeDialogHelper.dialogResult(handler(), -1));
m_dialog.setCancelable(m_buttonsList == null);
m_dialog.setCanceledOnTouchOutside(m_buttonsList == null);
m_dialog.setIcon(getIconDrawable());
@ -183,16 +176,13 @@ public class QtMessageDialogHelper
RelativeLayout dialogLayout = new RelativeLayout(m_activity);
int id = 1;
View lastView = null;
View.OnLongClickListener copyText = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
View.OnLongClickListener copyText = view -> {
TextView tv = (TextView)view;
if (tv != null) {
ClipboardManager cm = (android.text.ClipboardManager) m_activity.getSystemService(Context.CLIPBOARD_SERVICE);
ClipboardManager cm = (ClipboardManager) m_activity.getSystemService(Context.CLIPBOARD_SERVICE);
cm.setText(tv.getText());
}
return true;
}
};
if (m_text != null)
{
@ -316,20 +306,16 @@ public class QtMessageDialogHelper
scrollView.addView(dialogLayout);
m_dialog.setView(scrollView);
m_dialog.show();
}
});
}
@UsedFromNativeCode
public void hide()
{
m_activity.runOnUiThread( new Runnable() {
@Override
public void run() {
m_activity.runOnUiThread(() -> {
if (m_dialog != null && m_dialog.isShowing())
m_dialog.dismiss();
reset();
}
});
}

View File

@ -46,12 +46,7 @@ public class QtNative
private static final QtThread m_qtThread = new QtThread();
private static ClassLoader m_classLoader = null;
private static final Runnable runPendingCppRunnablesRunnable = new Runnable() {
@Override
public void run() {
runPendingCppRunnables();
}
};
private static final Runnable runPendingCppRunnablesRunnable = QtNative::runPendingCppRunnables;
public static boolean isStarted()
{
@ -255,12 +250,7 @@ public class QtNative
@UsedFromNativeCode
private static void setViewVisibility(final View view, final boolean visible)
{
runAction(new Runnable() {
@Override
public void run() {
view.setVisibility(visible ? View.VISIBLE : View.GONE);
}
});
runAction(() -> view.setVisibility(visible ? View.VISIBLE : View.GONE));
}
public static boolean startApplication(ArrayList<String> params, String mainLib)
@ -269,18 +259,8 @@ public class QtNative
synchronized (m_mainActivityMutex) {
String paramsStr = String.join("\t", params);
final String qtParams = mainLib + "\t" + paramsStr;
m_qtThread.run(new Runnable() {
@Override
public void run() {
res[0] = startQtAndroidPlugin(qtParams);
}
});
m_qtThread.post(new Runnable() {
@Override
public void run() {
startQtApplication();
}
});
m_qtThread.run(() -> res[0] = startQtAndroidPlugin(qtParams));
m_qtThread.post(QtNative::startQtApplication);
waitForServiceSetup();
m_started = true;
}
@ -289,9 +269,7 @@ public class QtNative
public static void quitApp()
{
runAction(new Runnable() {
@Override
public void run() {
runAction(() -> {
quitQtAndroidPlugin();
if (isActivityValid())
m_activity.get().finish();
@ -299,7 +277,6 @@ public class QtNative
m_service.get().stopSelf();
m_started = false;
}
});
}

View File

@ -45,12 +45,9 @@ public class QtThread {
public void run(final Runnable runnable) {
final Semaphore sem = new Semaphore(0);
synchronized (m_qtThread) {
m_pendingRunnables.add(new Runnable() {
@Override
public void run() {
m_pendingRunnables.add(() -> {
runnable.run();
sem.release();
}
});
m_qtThread.notify();
}

View File

@ -161,30 +161,21 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
public void notifyScrolledEvent(int viewId)
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
sendEventForVirtualViewId(viewId, AccessibilityEvent.TYPE_VIEW_SCROLLED);
}
});
QtNative.runAction(() -> sendEventForVirtualViewId(viewId,
AccessibilityEvent.TYPE_VIEW_SCROLLED));
}
public void notifyLocationChange(int viewId)
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
if (m_focusedVirtualViewId == viewId)
invalidateVirtualViewId(m_focusedVirtualViewId);
}
});
}
public void notifyObjectHide(int viewId, int parentId)
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
// If the object had accessibility focus, we need to clear it.
// Note: This code is mostly copied from
// AccessibilityNodeProvider::performAction, but we remove the
@ -198,30 +189,24 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
// When the object is hidden, we need to notify its parent about
// content change, not the hidden object itself
invalidateVirtualViewId(parentId);
}
});
}
public void notifyObjectFocus(int viewId)
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
if (m_view == null)
return;
m_focusedVirtualViewId = viewId;
m_view.invalidate();
sendEventForVirtualViewId(viewId,
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
}
});
}
public void notifyValueChanged(int viewId, String value)
{
QtNative.runAction(new Runnable() {
@Override
public void run() {
QtNative.runAction(() -> {
// Send a TYPE_ANNOUNCEMENT event with the new value
if ((viewId == INVALID_ID) || !m_manager.isEnabled()) {
@ -253,7 +238,6 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
if (!group.requestSendAccessibilityEvent(m_view, event))
Log.w(TAG, "Failed to send value change announcement for " + event.getClassName());
}
});
}