From 1907599bfd817e00c7f42b8cb941ebf93a098e7f Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Tue, 29 Sep 2020 11:48:04 +0300 Subject: Android: rename Android's package name for Qt 6 Rename Android package name org.qtproject.qt5.android to org.qtproject.qt.android to avoid inconsistency with Qt 6 name. Also, we include the major version number in the jar target. Task-number: QTBUG-86969 Change-Id: Ibb68947289be1079911b34ea157bf089cc52c47f Reviewed-by: Alexandru Croitor --- .../qtproject/qt/android/bindings/QtActivity.java | 1119 ++++++++++++++++++++ .../qt/android/bindings/QtActivityLoader.java | 164 +++ .../qt/android/bindings/QtApplication.java | 164 +++ .../qtproject/qt/android/bindings/QtLoader.java | 529 +++++++++ .../qtproject/qt/android/bindings/QtService.java | 156 +++ .../qt/android/bindings/QtServiceLoader.java | 80 ++ .../qtproject/qt5/android/bindings/QtActivity.java | 1119 -------------------- .../qt5/android/bindings/QtActivityLoader.java | 164 --- .../qt5/android/bindings/QtApplication.java | 164 --- .../qtproject/qt5/android/bindings/QtLoader.java | 529 --------- .../qtproject/qt5/android/bindings/QtService.java | 156 --- .../qt5/android/bindings/QtServiceLoader.java | 80 -- 12 files changed, 2212 insertions(+), 2212 deletions(-) create mode 100644 src/android/java/src/org/qtproject/qt/android/bindings/QtActivity.java create mode 100644 src/android/java/src/org/qtproject/qt/android/bindings/QtActivityLoader.java create mode 100644 src/android/java/src/org/qtproject/qt/android/bindings/QtApplication.java create mode 100644 src/android/java/src/org/qtproject/qt/android/bindings/QtLoader.java create mode 100644 src/android/java/src/org/qtproject/qt/android/bindings/QtService.java create mode 100644 src/android/java/src/org/qtproject/qt/android/bindings/QtServiceLoader.java delete mode 100644 src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java delete mode 100644 src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java delete mode 100644 src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java delete mode 100644 src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java delete mode 100644 src/android/java/src/org/qtproject/qt5/android/bindings/QtService.java delete mode 100644 src/android/java/src/org/qtproject/qt5/android/bindings/QtServiceLoader.java (limited to 'src/android/java/src') diff --git a/src/android/java/src/org/qtproject/qt/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt/android/bindings/QtActivity.java new file mode 100644 index 0000000000..1b34658300 --- /dev/null +++ b/src/android/java/src/org/qtproject/qt/android/bindings/QtActivity.java @@ -0,0 +1,1119 @@ +/* + Copyright (c) 2016, BogDan Vatra + Contact: http://www.qt.io/licensing/ + + Commercial License Usage + Licensees holding valid commercial Qt licenses may use this file in + accordance with the commercial license agreement provided with the + Software or, alternatively, in accordance with the terms contained in + a written agreement between you and The Qt Company. For licensing terms + and conditions see http://www.qt.io/terms-conditions. For further + information use the contact form at http://www.qt.io/contact-us. + + BSD License Usage + Alternatively, this file may be used under the BSD license as follows: + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package org.qtproject.qt.android.bindings; + +import android.app.Activity; +import android.app.Dialog; +import android.app.Fragment; +import android.content.Context; +import android.content.Intent; +import android.content.res.Configuration; +import android.content.res.Resources.Theme; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.os.Build; +import android.os.Bundle; +import android.util.AttributeSet; +import android.view.ActionMode; +import android.view.ActionMode.Callback; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.WindowManager.LayoutParams; +import android.view.accessibility.AccessibilityEvent; + +import org.qtproject.qt.android.QtNative; + +public class QtActivity extends Activity +{ + public String APPLICATION_PARAMETERS = null; // use this variable to pass any parameters to your application, + // the parameters must not contain any white spaces + // and must be separated with "\t" + // e.g "-param1\t-param2=value2\t-param3\tvalue3" + + public String ENVIRONMENT_VARIABLES = "QT_USE_ANDROID_NATIVE_DIALOGS=1"; + // use this variable to add any environment variables to your application. + // the env vars must be separated with "\t" + // e.g. "ENV_VAR1=1\tENV_VAR2=2\t" + // Currently the following vars are used by the android plugin: + // * QT_USE_ANDROID_NATIVE_DIALOGS - 1 to use the android native dialogs. + + public String[] QT_ANDROID_THEMES = null; // A list with all themes that your application want to use. + // The name of the theme must be the same with any theme from + // http://developer.android.com/reference/android/R.style.html + // The most used themes are: + // * "Theme" - (fallback) check http://developer.android.com/reference/android/R.style.html#Theme + // * "Theme_Black" - check http://developer.android.com/reference/android/R.style.html#Theme_Black + // * "Theme_Light" - (default for API <=10) check http://developer.android.com/reference/android/R.style.html#Theme_Light + // * "Theme_Holo" - check http://developer.android.com/reference/android/R.style.html#Theme_Holo + // * "Theme_Holo_Light" - (default for API 11-13) check http://developer.android.com/reference/android/R.style.html#Theme_Holo_Light + // * "Theme_DeviceDefault" - check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault + // * "Theme_DeviceDefault_Light" - (default for API 14+) check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault_Light + + public String QT_ANDROID_DEFAULT_THEME = null; // sets the default theme. + + private QtActivityLoader m_loader; + public QtActivity() + { + m_loader = new QtActivityLoader(this); + QT_ANDROID_THEMES = new String[] {"Theme_Holo_Light"}; + QT_ANDROID_DEFAULT_THEME = "Theme_Holo_Light"; + } + + + /////////////////////////// forward all notifications //////////////////////////// + /////////////////////////// Super class calls //////////////////////////////////// + /////////////// PLEASE DO NOT CHANGE THE FOLLOWING CODE ////////////////////////// + ////////////////////////////////////////////////////////////////////////////////// + + @Override + public boolean dispatchKeyEvent(KeyEvent event) + { + if (QtApplication.m_delegateObject != null && QtApplication.dispatchKeyEvent != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchKeyEvent, event); + else + return super.dispatchKeyEvent(event); + } + public boolean super_dispatchKeyEvent(KeyEvent event) + { + return super.dispatchKeyEvent(event); + } + //--------------------------------------------------------------------------- + + @Override + public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) + { + if (QtApplication.m_delegateObject != null && QtApplication.dispatchPopulateAccessibilityEvent != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchPopulateAccessibilityEvent, event); + else + return super.dispatchPopulateAccessibilityEvent(event); + } + public boolean super_dispatchPopulateAccessibilityEvent(AccessibilityEvent event) + { + return super.dispatchPopulateAccessibilityEvent(event); + } + //--------------------------------------------------------------------------- + + @Override + public boolean dispatchTouchEvent(MotionEvent ev) + { + if (QtApplication.m_delegateObject != null && QtApplication.dispatchTouchEvent != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchTouchEvent, ev); + else + return super.dispatchTouchEvent(ev); + } + public boolean super_dispatchTouchEvent(MotionEvent event) + { + return super.dispatchTouchEvent(event); + } + //--------------------------------------------------------------------------- + + @Override + public boolean dispatchTrackballEvent(MotionEvent ev) + { + if (QtApplication.m_delegateObject != null && QtApplication.dispatchTrackballEvent != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchTrackballEvent, ev); + else + return super.dispatchTrackballEvent(ev); + } + public boolean super_dispatchTrackballEvent(MotionEvent event) + { + return super.dispatchTrackballEvent(event); + } + //--------------------------------------------------------------------------- + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) + { + + if (QtApplication.m_delegateObject != null && QtApplication.onActivityResult != null) { + QtApplication.invokeDelegateMethod(QtApplication.onActivityResult, requestCode, resultCode, data); + return; + } + if (requestCode == QtLoader.MINISTRO_INSTALL_REQUEST_CODE) + m_loader.startApp(false); + super.onActivityResult(requestCode, resultCode, data); + } + public void super_onActivityResult(int requestCode, int resultCode, Intent data) + { + super.onActivityResult(requestCode, resultCode, data); + } + //--------------------------------------------------------------------------- + + @Override + protected void onApplyThemeResource(Theme theme, int resid, boolean first) + { + if (!QtApplication.invokeDelegate(theme, resid, first).invoked) + super.onApplyThemeResource(theme, resid, first); + } + public void super_onApplyThemeResource(Theme theme, int resid, boolean first) + { + super.onApplyThemeResource(theme, resid, first); + } + //--------------------------------------------------------------------------- + + + @Override + protected void onChildTitleChanged(Activity childActivity, CharSequence title) + { + if (!QtApplication.invokeDelegate(childActivity, title).invoked) + super.onChildTitleChanged(childActivity, title); + } + public void super_onChildTitleChanged(Activity childActivity, CharSequence title) + { + super.onChildTitleChanged(childActivity, title); + } + //--------------------------------------------------------------------------- + + @Override + public void onConfigurationChanged(Configuration newConfig) + { + if (!QtApplication.invokeDelegate(newConfig).invoked) + super.onConfigurationChanged(newConfig); + } + public void super_onConfigurationChanged(Configuration newConfig) + { + super.onConfigurationChanged(newConfig); + } + //--------------------------------------------------------------------------- + + @Override + public void onContentChanged() + { + if (!QtApplication.invokeDelegate().invoked) + super.onContentChanged(); + } + public void super_onContentChanged() + { + super.onContentChanged(); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onContextItemSelected(MenuItem item) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(item); + if (res.invoked) + return (Boolean)res.methodReturns; + else + return super.onContextItemSelected(item); + } + public boolean super_onContextItemSelected(MenuItem item) + { + return super.onContextItemSelected(item); + } + //--------------------------------------------------------------------------- + + @Override + public void onContextMenuClosed(Menu menu) + { + if (!QtApplication.invokeDelegate(menu).invoked) + super.onContextMenuClosed(menu); + } + public void super_onContextMenuClosed(Menu menu) + { + super.onContextMenuClosed(menu); + } + //--------------------------------------------------------------------------- + + protected void onCreateHook(Bundle savedInstanceState) { + m_loader.APPLICATION_PARAMETERS = APPLICATION_PARAMETERS; + m_loader.ENVIRONMENT_VARIABLES = ENVIRONMENT_VARIABLES; + m_loader.QT_ANDROID_THEMES = QT_ANDROID_THEMES; + m_loader.QT_ANDROID_DEFAULT_THEME = QT_ANDROID_DEFAULT_THEME; + m_loader.onCreate(savedInstanceState); + } + + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + onCreateHook(savedInstanceState); + } + //--------------------------------------------------------------------------- + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) + { + if (!QtApplication.invokeDelegate(menu, v, menuInfo).invoked) + super.onCreateContextMenu(menu, v, menuInfo); + } + public void super_onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) + { + super.onCreateContextMenu(menu, v, menuInfo); + } + //--------------------------------------------------------------------------- + + @Override + public CharSequence onCreateDescription() + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(); + if (res.invoked) + return (CharSequence)res.methodReturns; + else + return super.onCreateDescription(); + } + public CharSequence super_onCreateDescription() + { + return super.onCreateDescription(); + } + //--------------------------------------------------------------------------- + + @Override + protected Dialog onCreateDialog(int id) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(id); + if (res.invoked) + return (Dialog)res.methodReturns; + else + return super.onCreateDialog(id); + } + public Dialog super_onCreateDialog(int id) + { + return super.onCreateDialog(id); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onCreateOptionsMenu(Menu menu) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(menu); + if (res.invoked) + return (Boolean)res.methodReturns; + else + return super.onCreateOptionsMenu(menu); + } + public boolean super_onCreateOptionsMenu(Menu menu) + { + return super.onCreateOptionsMenu(menu); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onCreatePanelMenu(int featureId, Menu menu) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId, menu); + if (res.invoked) + return (Boolean)res.methodReturns; + else + return super.onCreatePanelMenu(featureId, menu); + } + public boolean super_onCreatePanelMenu(int featureId, Menu menu) + { + return super.onCreatePanelMenu(featureId, menu); + } + //--------------------------------------------------------------------------- + + + @Override + public View onCreatePanelView(int featureId) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId); + if (res.invoked) + return (View)res.methodReturns; + else + return super.onCreatePanelView(featureId); + } + public View super_onCreatePanelView(int featureId) + { + return super.onCreatePanelView(featureId); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onCreateThumbnail(Bitmap outBitmap, Canvas canvas) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(outBitmap, canvas); + if (res.invoked) + return (Boolean)res.methodReturns; + else + return super.onCreateThumbnail(outBitmap, canvas); + } + public boolean super_onCreateThumbnail(Bitmap outBitmap, Canvas canvas) + { + return super.onCreateThumbnail(outBitmap, canvas); + } + //--------------------------------------------------------------------------- + + @Override + public View onCreateView(String name, Context context, AttributeSet attrs) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(name, context, attrs); + if (res.invoked) + return (View)res.methodReturns; + else + return super.onCreateView(name, context, attrs); + } + public View super_onCreateView(String name, Context context, AttributeSet attrs) + { + return super.onCreateView(name, context, attrs); + } + //--------------------------------------------------------------------------- + + @Override + protected void onDestroy() + { + super.onDestroy(); + QtApplication.invokeDelegate(); + } + //--------------------------------------------------------------------------- + + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + if (QtApplication.m_delegateObject != null && QtApplication.onKeyDown != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyDown, keyCode, event); + else + return super.onKeyDown(keyCode, event); + } + public boolean super_onKeyDown(int keyCode, KeyEvent event) + { + return super.onKeyDown(keyCode, event); + } + //--------------------------------------------------------------------------- + + + @Override + public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) + { + if (QtApplication.m_delegateObject != null && QtApplication.onKeyMultiple != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyMultiple, keyCode, repeatCount, event); + else + return super.onKeyMultiple(keyCode, repeatCount, event); + } + public boolean super_onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) + { + return super.onKeyMultiple(keyCode, repeatCount, event); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onKeyUp(int keyCode, KeyEvent event) + { + if (QtApplication.m_delegateObject != null && QtApplication.onKeyUp != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyUp, keyCode, event); + else + return super.onKeyUp(keyCode, event); + } + public boolean super_onKeyUp(int keyCode, KeyEvent event) + { + return super.onKeyUp(keyCode, event); + } + //--------------------------------------------------------------------------- + + @Override + public void onLowMemory() + { + if (!QtApplication.invokeDelegate().invoked) + super.onLowMemory(); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId, item); + if (res.invoked) + return (Boolean)res.methodReturns; + else + return super.onMenuItemSelected(featureId, item); + } + public boolean super_onMenuItemSelected(int featureId, MenuItem item) + { + return super.onMenuItemSelected(featureId, item); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onMenuOpened(int featureId, Menu menu) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId, menu); + if (res.invoked) + return (Boolean)res.methodReturns; + else + return super.onMenuOpened(featureId, menu); + } + public boolean super_onMenuOpened(int featureId, Menu menu) + { + return super.onMenuOpened(featureId, menu); + } + //--------------------------------------------------------------------------- + + @Override + protected void onNewIntent(Intent intent) + { + if (!QtApplication.invokeDelegate(intent).invoked) + super.onNewIntent(intent); + } + public void super_onNewIntent(Intent intent) + { + super.onNewIntent(intent); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onOptionsItemSelected(MenuItem item) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(item); + if (res.invoked) + return (Boolean)res.methodReturns; + else + return super.onOptionsItemSelected(item); + } + public boolean super_onOptionsItemSelected(MenuItem item) + { + return super.onOptionsItemSelected(item); + } + //--------------------------------------------------------------------------- + + @Override + public void onOptionsMenuClosed(Menu menu) + { + if (!QtApplication.invokeDelegate(menu).invoked) + super.onOptionsMenuClosed(menu); + } + public void super_onOptionsMenuClosed(Menu menu) + { + super.onOptionsMenuClosed(menu); + } + //--------------------------------------------------------------------------- + + @Override + public void onPanelClosed(int featureId, Menu menu) + { + if (!QtApplication.invokeDelegate(featureId, menu).invoked) + super.onPanelClosed(featureId, menu); + } + public void super_onPanelClosed(int featureId, Menu menu) + { + super.onPanelClosed(featureId, menu); + } + //--------------------------------------------------------------------------- + + @Override + protected void onPause() + { + super.onPause(); + QtApplication.invokeDelegate(); + } + //--------------------------------------------------------------------------- + + @Override + protected void onPostCreate(Bundle savedInstanceState) + { + super.onPostCreate(savedInstanceState); + QtApplication.invokeDelegate(savedInstanceState); + } + //--------------------------------------------------------------------------- + + @Override + protected void onPostResume() + { + super.onPostResume(); + QtApplication.invokeDelegate(); + } + //--------------------------------------------------------------------------- + + @Override + protected void onPrepareDialog(int id, Dialog dialog) + { + if (!QtApplication.invokeDelegate(id, dialog).invoked) + super.onPrepareDialog(id, dialog); + } + public void super_onPrepareDialog(int id, Dialog dialog) + { + super.onPrepareDialog(id, dialog); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onPrepareOptionsMenu(Menu menu) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(menu); + if (res.invoked) + return (Boolean)res.methodReturns; + else + return super.onPrepareOptionsMenu(menu); + } + public boolean super_onPrepareOptionsMenu(Menu menu) + { + return super.onPrepareOptionsMenu(menu); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onPreparePanel(int featureId, View view, Menu menu) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId, view, menu); + if (res.invoked) + return (Boolean)res.methodReturns; + else + return super.onPreparePanel(featureId, view, menu); + } + public boolean super_onPreparePanel(int featureId, View view, Menu menu) + { + return super.onPreparePanel(featureId, view, menu); + } + //--------------------------------------------------------------------------- + + @Override + protected void onRestart() + { + super.onRestart(); + QtApplication.invokeDelegate(); + } + //--------------------------------------------------------------------------- + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) + { + if (!QtApplication.invokeDelegate(savedInstanceState).invoked) + super.onRestoreInstanceState(savedInstanceState); + } + public void super_onRestoreInstanceState(Bundle savedInstanceState) + { + super.onRestoreInstanceState(savedInstanceState); + } + //--------------------------------------------------------------------------- + + @Override + protected void onResume() + { + super.onResume(); + QtApplication.invokeDelegate(); + } + //--------------------------------------------------------------------------- + + @Override + public Object onRetainNonConfigurationInstance() + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(); + if (res.invoked) + return res.methodReturns; + else + return super.onRetainNonConfigurationInstance(); + } + public Object super_onRetainNonConfigurationInstance() + { + return super.onRetainNonConfigurationInstance(); + } + //--------------------------------------------------------------------------- + + @Override + protected void onSaveInstanceState(Bundle outState) + { + if (!QtApplication.invokeDelegate(outState).invoked) + super.onSaveInstanceState(outState); + } + public void super_onSaveInstanceState(Bundle outState) + { + super.onSaveInstanceState(outState); + + } + //--------------------------------------------------------------------------- + + @Override + public boolean onSearchRequested() + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(); + if (res.invoked) + return (Boolean)res.methodReturns; + else + return super.onSearchRequested(); + } + public boolean super_onSearchRequested() + { + return super.onSearchRequested(); + } + //--------------------------------------------------------------------------- + + @Override + protected void onStart() + { + super.onStart(); + QtApplication.invokeDelegate(); + } + //--------------------------------------------------------------------------- + + @Override + protected void onStop() + { + super.onStop(); + QtApplication.invokeDelegate(); + } + //--------------------------------------------------------------------------- + + @Override + protected void onTitleChanged(CharSequence title, int color) + { + if (!QtApplication.invokeDelegate(title, color).invoked) + super.onTitleChanged(title, color); + } + public void super_onTitleChanged(CharSequence title, int color) + { + super.onTitleChanged(title, color); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onTouchEvent(MotionEvent event) + { + if (QtApplication.m_delegateObject != null && QtApplication.onTouchEvent != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onTouchEvent, event); + else + return super.onTouchEvent(event); + } + public boolean super_onTouchEvent(MotionEvent event) + { + return super.onTouchEvent(event); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onTrackballEvent(MotionEvent event) + { + if (QtApplication.m_delegateObject != null && QtApplication.onTrackballEvent != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onTrackballEvent, event); + else + return super.onTrackballEvent(event); + } + public boolean super_onTrackballEvent(MotionEvent event) + { + return super.onTrackballEvent(event); + } + //--------------------------------------------------------------------------- + + @Override + public void onUserInteraction() + { + if (!QtApplication.invokeDelegate().invoked) + super.onUserInteraction(); + } + public void super_onUserInteraction() + { + super.onUserInteraction(); + } + //--------------------------------------------------------------------------- + + @Override + protected void onUserLeaveHint() + { + if (!QtApplication.invokeDelegate().invoked) + super.onUserLeaveHint(); + } + public void super_onUserLeaveHint() + { + super.onUserLeaveHint(); + } + //--------------------------------------------------------------------------- + + @Override + public void onWindowAttributesChanged(LayoutParams params) + { + if (!QtApplication.invokeDelegate(params).invoked) + super.onWindowAttributesChanged(params); + } + public void super_onWindowAttributesChanged(LayoutParams params) + { + super.onWindowAttributesChanged(params); + } + //--------------------------------------------------------------------------- + + @Override + public void onWindowFocusChanged(boolean hasFocus) + { + if (!QtApplication.invokeDelegate(hasFocus).invoked) + super.onWindowFocusChanged(hasFocus); + } + public void super_onWindowFocusChanged(boolean hasFocus) + { + super.onWindowFocusChanged(hasFocus); + } + //--------------------------------------------------------------------------- + + //////////////// Activity API 5 ///////////// +//@ANDROID-5 + @Override + public void onAttachedToWindow() + { + if (!QtApplication.invokeDelegate().invoked) + super.onAttachedToWindow(); + } + public void super_onAttachedToWindow() + { + super.onAttachedToWindow(); + } + //--------------------------------------------------------------------------- + + @Override + public void onBackPressed() + { + if (!QtApplication.invokeDelegate().invoked) + super.onBackPressed(); + } + public void super_onBackPressed() + { + super.onBackPressed(); + } + //--------------------------------------------------------------------------- + + @Override + public void onDetachedFromWindow() + { + if (!QtApplication.invokeDelegate().invoked) + super.onDetachedFromWindow(); + } + public void super_onDetachedFromWindow() + { + super.onDetachedFromWindow(); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onKeyLongPress(int keyCode, KeyEvent event) + { + if (QtApplication.m_delegateObject != null && QtApplication.onKeyLongPress != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyLongPress, keyCode, event); + else + return super.onKeyLongPress(keyCode, event); + } + public boolean super_onKeyLongPress(int keyCode, KeyEvent event) + { + return super.onKeyLongPress(keyCode, event); + } + //--------------------------------------------------------------------------- +//@ANDROID-5 + +//////////////// Activity API 8 ///////////// +//@ANDROID-8 +@Override + protected Dialog onCreateDialog(int id, Bundle args) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(id, args); + if (res.invoked) + return (Dialog)res.methodReturns; + else + return super.onCreateDialog(id, args); + } + public Dialog super_onCreateDialog(int id, Bundle args) + { + return super.onCreateDialog(id, args); + } + //--------------------------------------------------------------------------- + + @Override + protected void onPrepareDialog(int id, Dialog dialog, Bundle args) + { + if (!QtApplication.invokeDelegate(id, dialog, args).invoked) + super.onPrepareDialog(id, dialog, args); + } + public void super_onPrepareDialog(int id, Dialog dialog, Bundle args) + { + super.onPrepareDialog(id, dialog, args); + } + //--------------------------------------------------------------------------- +//@ANDROID-8 + //////////////// Activity API 11 ///////////// + +//@ANDROID-11 + @Override + public boolean dispatchKeyShortcutEvent(KeyEvent event) + { + if (QtApplication.m_delegateObject != null && QtApplication.dispatchKeyShortcutEvent != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchKeyShortcutEvent, event); + else + return super.dispatchKeyShortcutEvent(event); + } + public boolean super_dispatchKeyShortcutEvent(KeyEvent event) + { + return super.dispatchKeyShortcutEvent(event); + } + //--------------------------------------------------------------------------- + + @Override + public void onActionModeFinished(ActionMode mode) + { + if (!QtApplication.invokeDelegate(mode).invoked) + super.onActionModeFinished(mode); + } + public void super_onActionModeFinished(ActionMode mode) + { + super.onActionModeFinished(mode); + } + //--------------------------------------------------------------------------- + + @Override + public void onActionModeStarted(ActionMode mode) + { + if (!QtApplication.invokeDelegate(mode).invoked) + super.onActionModeStarted(mode); + } + public void super_onActionModeStarted(ActionMode mode) + { + super.onActionModeStarted(mode); + } + //--------------------------------------------------------------------------- + + @Override + public void onAttachFragment(Fragment fragment) + { + if (!QtApplication.invokeDelegate(fragment).invoked) + super.onAttachFragment(fragment); + } + public void super_onAttachFragment(Fragment fragment) + { + super.onAttachFragment(fragment); + } + //--------------------------------------------------------------------------- + + @Override + public View onCreateView(View parent, String name, Context context, AttributeSet attrs) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(parent, name, context, attrs); + if (res.invoked) + return (View)res.methodReturns; + else + return super.onCreateView(parent, name, context, attrs); + } + public View super_onCreateView(View parent, String name, Context context, + AttributeSet attrs) { + return super.onCreateView(parent, name, context, attrs); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onKeyShortcut(int keyCode, KeyEvent event) + { + if (QtApplication.m_delegateObject != null && QtApplication.onKeyShortcut != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyShortcut, keyCode,event); + else + return super.onKeyShortcut(keyCode, event); + } + public boolean super_onKeyShortcut(int keyCode, KeyEvent event) + { + return super.onKeyShortcut(keyCode, event); + } + //--------------------------------------------------------------------------- + + @Override + public ActionMode onWindowStartingActionMode(Callback callback) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(callback); + if (res.invoked) + return (ActionMode)res.methodReturns; + else + return super.onWindowStartingActionMode(callback); + } + public ActionMode super_onWindowStartingActionMode(Callback callback) + { + return super.onWindowStartingActionMode(callback); + } + //--------------------------------------------------------------------------- +//@ANDROID-11 + //////////////// Activity API 12 ///////////// + +//@ANDROID-12 + @Override + public boolean dispatchGenericMotionEvent(MotionEvent ev) + { + if (QtApplication.m_delegateObject != null && QtApplication.dispatchGenericMotionEvent != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchGenericMotionEvent, ev); + else + return super.dispatchGenericMotionEvent(ev); + } + public boolean super_dispatchGenericMotionEvent(MotionEvent event) + { + return super.dispatchGenericMotionEvent(event); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onGenericMotionEvent(MotionEvent event) + { + if (QtApplication.m_delegateObject != null && QtApplication.onGenericMotionEvent != null) + return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onGenericMotionEvent, event); + else + return super.onGenericMotionEvent(event); + } + public boolean super_onGenericMotionEvent(MotionEvent event) + { + return super.onGenericMotionEvent(event); + } + //--------------------------------------------------------------------------- +//@ANDROID-12 + + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) + { + if (QtApplication.m_delegateObject != null && QtApplication.onRequestPermissionsResult != null) { + QtApplication.invokeDelegateMethod(QtApplication.onRequestPermissionsResult, requestCode , permissions, grantResults); + return; + } + } + + public void bringChildToBack(int id) + { + QtNative.activityDelegate().bringChildToBack(id); + } + + public void bringChildToFront(int id) + { + QtNative.activityDelegate().bringChildToFront(id); + } + + public void closeContextMenu() + { + QtNative.activityDelegate().closeContextMenu(); + } + + public void createSurface(int id, boolean onTop, int x, int y, int w, int h, int imageDepth) + { + QtNative.activityDelegate().createSurface(id, onTop, x, y, w, h, imageDepth); + } + + public void destroySurface(int id) + { + QtNative.activityDelegate().destroySurface(id); + } + + public int getSurfaceCount() + { + return QtNative.activityDelegate().getSurfaceCount(); + } + + public void hideSoftwareKeyboard() + { + QtNative.activityDelegate().hideSoftwareKeyboard(); + } + + public void hideSplashScreen() + { + QtNative.activityDelegate().hideSplashScreen(); + } + + public void hideSplashScreen(final int duration) + { + QtNative.activityDelegate().hideSplashScreen(duration); + } + + public void initializeAccessibility() + { + QtNative.activityDelegate().initializeAccessibility(); + } + + public void insertNativeView(int id, View view, int x, int y, int w, int h) + { + QtNative.activityDelegate().insertNativeView(id, view, x, y, w, h); + } + + public boolean loadApplication(Activity activity, ClassLoader classLoader, Bundle loaderParams) + { + return QtNative.activityDelegate().loadApplication(activity, classLoader, loaderParams); + } + + public void onCreatePopupMenu(Menu menu) + { + QtNative.activityDelegate().onCreatePopupMenu(menu); + } + + public void onTerminate() + { + QtNative.activityDelegate().onTerminate(); + } + + public void openContextMenu(final int x, final int y, final int w, final int h) + { + QtNative.activityDelegate().openContextMenu(x, y, w, h); + } + + public void resetOptionsMenu() + { + QtNative.activityDelegate().resetOptionsMenu(); + } + + public void resetSoftwareKeyboard() + { + QtNative.activityDelegate().resetSoftwareKeyboard(); + } + + public boolean setKeyboardVisibility(boolean visibility, long timeStamp) + { + return QtNative.activityDelegate().setKeyboardVisibility(visibility, timeStamp); + } + + public void setSurfaceGeometry(int id, int x, int y, int w, int h) + { + QtNative.activityDelegate().setSurfaceGeometry(id, x, y, w, h); + } + + public void setSystemUiVisibility(int systemUiVisibility) + { + QtNative.activityDelegate().setSystemUiVisibility(systemUiVisibility); + } + + public void showSoftwareKeyboard(final int x, final int y, final int width, + final int height, final int inputHints, + final int enterKeyType) + { + QtNative.activityDelegate().showSoftwareKeyboard(x, y, width, height, inputHints, enterKeyType); + } + + public boolean startApplication() + { + return QtNative.activityDelegate().startApplication(); + } + + public void updateFullScreen() + { + QtNative.activityDelegate().updateFullScreen(); + } + + public void updateHandles(int mode, int editX, int editY, int editButtons, + int x1, int y1, int x2, int y2, boolean rtl) + { + QtNative.activityDelegate().updateHandles(mode, editX, editY, editButtons, x1, y1, x2, y2, rtl); + } + + public void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd) + { + QtNative.activityDelegate().updateSelection(selStart, selEnd, candidatesStart, candidatesEnd); + } +} diff --git a/src/android/java/src/org/qtproject/qt/android/bindings/QtActivityLoader.java b/src/android/java/src/org/qtproject/qt/android/bindings/QtActivityLoader.java new file mode 100644 index 0000000000..da6b01c9a7 --- /dev/null +++ b/src/android/java/src/org/qtproject/qt/android/bindings/QtActivityLoader.java @@ -0,0 +1,164 @@ +/* + Copyright (c) 2016, BogDan Vatra + Contact: http://www.qt-project.org/legal + + Commercial License Usage + Licensees holding valid commercial Qt licenses may use this file in + accordance with the commercial license agreement provided with the + Software or, alternatively, in accordance with the terms contained in + a written agreement between you and Digia. For licensing terms and + conditions see http://qt.digia.com/licensing. For further information + use the contact form at http://qt.digia.com/contact-us. + + BSD License Usage + Alternatively, this file may be used under the BSD license as follows: + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package org.qtproject.qt.android.bindings; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.graphics.drawable.ColorDrawable; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.view.Window; + + +import java.lang.reflect.Field; + +public class QtActivityLoader extends QtLoader { + QtActivity m_activity; + + QtActivityLoader(QtActivity activity) + { + super(activity, QtActivity.class); + m_activity = activity; + } + @Override + protected void downloadUpgradeMinistro(String msg) { + AlertDialog.Builder downloadDialog = new AlertDialog.Builder(m_activity); + downloadDialog.setMessage(msg); + downloadDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + try { + Uri uri = Uri.parse("market://details?id=org.kde.necessitas.ministro"); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + m_activity.startActivityForResult(intent, MINISTRO_INSTALL_REQUEST_CODE); + } catch (Exception e) { + e.printStackTrace(); + ministroNotFound(); + } + } + }); + + downloadDialog.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + m_activity.finish(); + } + }); + downloadDialog.show(); + } + + @Override + protected String loaderClassName() { + return "org.qtproject.qt.android.QtActivityDelegate"; + } + + @Override + protected Class contextClassName() { + return android.app.Activity.class; + } + + @Override + protected void finish() { + m_activity.finish(); + } + + @Override + protected String getTitle() { + return (String) m_activity.getTitle(); + } + + @Override + protected void runOnUiThread(Runnable run) { + m_activity.runOnUiThread(run); + } + + @Override + Intent getIntent() { + return m_activity.getIntent(); + } + + public void onCreate(Bundle savedInstanceState) { + try { + m_contextInfo = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), PackageManager.GET_META_DATA); + int theme = ((ActivityInfo)m_contextInfo).getThemeResource(); + for (Field f : Class.forName("android.R$style").getDeclaredFields()) { + if (f.getInt(null) == theme) { + QT_ANDROID_THEMES = new String[] {f.getName()}; + QT_ANDROID_DEFAULT_THEME = f.getName(); + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + finish(); + return; + } + + try { + m_activity.setTheme(Class.forName("android.R$style").getDeclaredField(QT_ANDROID_DEFAULT_THEME).getInt(null)); + } catch (Exception e) { + e.printStackTrace(); + } + + m_activity.requestWindowFeature(Window.FEATURE_ACTION_BAR); + + if (QtApplication.m_delegateObject != null && QtApplication.onCreate != null) { + QtApplication.invokeDelegateMethod(QtApplication.onCreate, savedInstanceState); + return; + } + + m_displayDensity = m_activity.getResources().getDisplayMetrics().densityDpi; + + ENVIRONMENT_VARIABLES += "\tQT_ANDROID_THEME=" + QT_ANDROID_DEFAULT_THEME + + "/\tQT_ANDROID_THEME_DISPLAY_DPI=" + m_displayDensity + "\t"; + + if (null == m_activity.getLastNonConfigurationInstance()) { + if (m_contextInfo.metaData.containsKey("android.app.background_running") + && m_contextInfo.metaData.getBoolean("android.app.background_running")) { + ENVIRONMENT_VARIABLES += "QT_BLOCK_EVENT_LOOPS_WHEN_SUSPENDED=0\t"; + } else { + ENVIRONMENT_VARIABLES += "QT_BLOCK_EVENT_LOOPS_WHEN_SUSPENDED=1\t"; + } + + startApp(true); + } + } +} diff --git a/src/android/java/src/org/qtproject/qt/android/bindings/QtApplication.java b/src/android/java/src/org/qtproject/qt/android/bindings/QtApplication.java new file mode 100644 index 0000000000..34a3bc28ea --- /dev/null +++ b/src/android/java/src/org/qtproject/qt/android/bindings/QtApplication.java @@ -0,0 +1,164 @@ +/* + Copyright (c) 2016, BogDan Vatra + Contact: http://www.qt.io/licensing/ + + Commercial License Usage + Licensees holding valid commercial Qt licenses may use this file in + accordance with the commercial license agreement provided with the + Software or, alternatively, in accordance with the terms contained in + a written agreement between you and The Qt Company. For licensing terms + and conditions see http://www.qt.io/terms-conditions. For further + information use the contact form at http://www.qt.io/contact-us. + + BSD License Usage + Alternatively, this file may be used under the BSD license as follows: + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package org.qtproject.qt.android.bindings; + +import android.app.Application; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; + +public class QtApplication extends Application +{ + public final static String QtTAG = "Qt"; + public static Object m_delegateObject = null; + public static HashMap> m_delegateMethods= new HashMap>(); + public static Method dispatchKeyEvent = null; + public static Method dispatchPopulateAccessibilityEvent = null; + public static Method dispatchTouchEvent = null; + public static Method dispatchTrackballEvent = null; + public static Method onKeyDown = null; + public static Method onKeyMultiple = null; + public static Method onKeyUp = null; + public static Method onTouchEvent = null; + public static Method onTrackballEvent = null; + public static Method onActivityResult = null; + public static Method onCreate = null; + public static Method onKeyLongPress = null; + public static Method dispatchKeyShortcutEvent = null; + public static Method onKeyShortcut = null; + public static Method dispatchGenericMotionEvent = null; + public static Method onGenericMotionEvent = null; + public static Method onRequestPermissionsResult = null; + private static String activityClassName; + public static void setQtContextDelegate(Class clazz, Object listener) + { + m_delegateObject = listener; + activityClassName = clazz.getCanonicalName(); + + ArrayList delegateMethods = new ArrayList(); + for (Method m : listener.getClass().getMethods()) { + if (m.getDeclaringClass().getName().startsWith("org.qtproject.qt.android")) + delegateMethods.add(m); + } + + ArrayList applicationFields = new ArrayList(); + for (Field f : QtApplication.class.getFields()) { + if (f.getDeclaringClass().getName().equals(QtApplication.class.getName())) + applicationFields.add(f); + } + + for (Method delegateMethod : delegateMethods) { + try { + clazz.getDeclaredMethod(delegateMethod.getName(), delegateMethod.getParameterTypes()); + if (QtApplication.m_delegateMethods.containsKey(delegateMethod.getName())) { + QtApplication.m_delegateMethods.get(delegateMethod.getName()).add(delegateMethod); + } else { + ArrayList delegateSet = new ArrayList(); + delegateSet.add(delegateMethod); + QtApplication.m_delegateMethods.put(delegateMethod.getName(), delegateSet); + } + for (Field applicationField:applicationFields) { + if (applicationField.getName().equals(delegateMethod.getName())) { + try { + applicationField.set(null, delegateMethod); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @Override + public void onTerminate() { + if (m_delegateObject != null && m_delegateMethods.containsKey("onTerminate")) + invokeDelegateMethod(m_delegateMethods.get("onTerminate").get(0)); + super.onTerminate(); + } + + public static class InvokeResult + { + public boolean invoked = false; + public Object methodReturns = null; + } + + private static int stackDeep=-1; + public static InvokeResult invokeDelegate(Object... args) + { + InvokeResult result = new InvokeResult(); + if (m_delegateObject == null) + return result; + StackTraceElement[] elements = Thread.currentThread().getStackTrace(); + if (-1 == stackDeep) { + for (int it=0;it + Contact: http://www.qt.io/licensing/ + + Commercial License Usage + Licensees holding valid commercial Qt licenses may use this file in + accordance with the commercial license agreement provided with the + Software or, alternatively, in accordance with the terms contained in + a written agreement between you and The Qt Company. For licensing terms + and conditions see http://www.qt.io/terms-conditions. For further + information use the contact form at http://www.qt.io/contact-us. + + BSD License Usage + Alternatively, this file may be used under the BSD license as follows: + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package org.qtproject.qt.android.bindings; + +import android.app.AlertDialog; +import android.content.ComponentName; +import android.content.Context; +import android.content.ContextWrapper; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.pm.ComponentInfo; +import android.os.Build; +import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; + +import org.kde.necessitas.ministro.IMinistro; +import org.kde.necessitas.ministro.IMinistroCallback; + +import java.io.File; +import java.io.FileOutputStream; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import dalvik.system.DexClassLoader; + +public abstract class QtLoader { + + public final static int MINISTRO_INSTALL_REQUEST_CODE = 0xf3ee; // request code used to know when Ministro instalation is finished + public static final int MINISTRO_API_LEVEL = 5; // Ministro api level (check IMinistro.aidl file) + public static final int NECESSITAS_API_LEVEL = 2; // Necessitas api level used by platform plugin + public static final int QT_VERSION = 0x050700; // This app requires at least Qt version 5.7.0 + + public static final String ERROR_CODE_KEY = "error.code"; + public static final String ERROR_MESSAGE_KEY = "error.message"; + public static final String DEX_PATH_KEY = "dex.path"; + public static final String LIB_PATH_KEY = "lib.path"; + public static final String LOADER_CLASS_NAME_KEY = "loader.class.name"; + public static final String NATIVE_LIBRARIES_KEY = "native.libraries"; + public static final String ENVIRONMENT_VARIABLES_KEY = "environment.variables"; + public static final String APPLICATION_PARAMETERS_KEY = "application.parameters"; + public static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries"; + public static final String MAIN_LIBRARY_KEY = "main.library"; + public static final String STATIC_INIT_CLASSES_KEY = "static.init.classes"; + public static final String NECESSITAS_API_LEVEL_KEY = "necessitas.api.level"; + public static final String EXTRACT_STYLE_KEY = "extract.android.style"; + private static final String EXTRACT_STYLE_MINIMAL_KEY = "extract.android.style.option"; + + // These parameters matter in case of deploying application as system (embedded into firmware) + public static final String SYSTEM_LIB_PATH = "/system/lib/"; + public String[] SYSTEM_APP_PATHS = {"/system/priv-app/", "/system/app/"}; + + /// Ministro server parameter keys + public static final String REQUIRED_MODULES_KEY = "required.modules"; + public static final String APPLICATION_TITLE_KEY = "application.title"; + public static final String MINIMUM_MINISTRO_API_KEY = "minimum.ministro.api"; + public static final String MINIMUM_QT_VERSION_KEY = "minimum.qt.version"; + public static final String SOURCES_KEY = "sources"; // needs MINISTRO_API_LEVEL >=3 !!! + // Use this key to specify any 3rd party sources urls + // Ministro will download these repositories into their + // own folders, check http://community.kde.org/Necessitas/Ministro + // for more details. + + public static final String REPOSITORY_KEY = "repository"; // use this key to overwrite the default ministro repsitory + public static final String ANDROID_THEMES_KEY = "android.themes"; // themes that your application uses + + public String APPLICATION_PARAMETERS = null; // use this variable to pass any parameters to your application, + // the parameters must not contain any white spaces + // and must be separated with "\t" + // e.g "-param1\t-param2=value2\t-param3\tvalue3" + + public String ENVIRONMENT_VARIABLES = "QT_USE_ANDROID_NATIVE_DIALOGS=1"; + // use this variable to add any environment variables to your application. + // the env vars must be separated with "\t" + // e.g. "ENV_VAR1=1\tENV_VAR2=2\t" + // Currently the following vars are used by the android plugin: + // * QT_USE_ANDROID_NATIVE_DIALOGS -1 to use the android native dialogs. + + public String[] QT_ANDROID_THEMES = null; // A list with all themes that your application want to use. + // The name of the theme must be the same with any theme from + // http://developer.android.com/reference/android/R.style.html + // The most used themes are: + // * "Theme" - (fallback) check http://developer.android.com/reference/android/R.style.html#Theme + // * "Theme_Black" - check http://developer.android.com/reference/android/R.style.html#Theme_Black + // * "Theme_Light" - (default for API <=10) check http://developer.android.com/reference/android/R.style.html#Theme_Light + // * "Theme_Holo" - check http://developer.android.com/reference/android/R.style.html#Theme_Holo + // * "Theme_Holo_Light" - (default for API 11-13) check http://developer.android.com/reference/android/R.style.html#Theme_Holo_Light + // * "Theme_DeviceDefault" - check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault + // * "Theme_DeviceDefault_Light" - (default for API 14+) check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault_Light + + public String QT_ANDROID_DEFAULT_THEME = null; // sets the default theme. + + public static final int INCOMPATIBLE_MINISTRO_VERSION = 1; // Incompatible Ministro version. Ministro needs to be upgraded. + + public String[] m_sources = {"https://download.qt-project.org/ministro/android/qt5/qt-5.7"}; // Make sure you are using ONLY secure locations + public String m_repository = "default"; // Overwrites the default Ministro repository + // Possible values: + // * default - Ministro default repository set with "Ministro configuration tool". + // By default the stable version is used. Only this or stable repositories should + // be used in production. + // * stable - stable repository, only this and default repositories should be used + // in production. + // * testing - testing repository, DO NOT use this repository in production, + // this repository is used to push a new release, and should be used to test your application. + // * unstable - unstable repository, DO NOT use this repository in production, + // this repository is used to push Qt snapshots. + public ArrayList m_qtLibs = null; // required qt libs + public int m_displayDensity = -1; + private ContextWrapper m_context; + protected ComponentInfo m_contextInfo; + private Class m_delegateClass; + + private static ArrayList m_fileOutputStreams = new ArrayList(); + // List of open file streams associated with files copied during installation. + + QtLoader(ContextWrapper context, Class clazz) { + m_context = context; + m_delegateClass = clazz; + } + + // Implement in subclass + protected void finish() {} + + protected String getTitle() { + return "Qt"; + } + + protected void runOnUiThread(Runnable run) { + run.run(); + } + protected void downloadUpgradeMinistro(String msg) + { + Log.e(QtApplication.QtTAG, msg); + } + + protected abstract String loaderClassName(); + protected abstract Class contextClassName(); + + Intent getIntent() + { + return null; + } + // Implement in subclass + + private final List supportedAbis = Arrays.asList(Build.SUPPORTED_ABIS); + private String preferredAbi = null; + + private ArrayList prefferedAbiLibs(String []libs) + { + HashMap> abisLibs = new HashMap<>(); + for (String lib : libs) { + String[] archLib = lib.split(";", 2); + if (preferredAbi != null && !archLib[0].equals(preferredAbi)) + continue; + if (!abisLibs.containsKey(archLib[0])) + abisLibs.put(archLib[0], new ArrayList()); + abisLibs.get(archLib[0]).add(archLib[1]); + } + + if (preferredAbi != null) { + if (abisLibs.containsKey(preferredAbi)) { + return abisLibs.get(preferredAbi); + } + return new ArrayList(); + } + + for (String abi: supportedAbis) { + if (abisLibs.containsKey(abi)) { + preferredAbi = abi; + return abisLibs.get(abi); + } + } + return new ArrayList(); + } + + // this function is used to load and start the loader + private void loadApplication(Bundle loaderParams) + { + try { + final int errorCode = loaderParams.getInt(ERROR_CODE_KEY); + if (errorCode != 0) { + if (errorCode == INCOMPATIBLE_MINISTRO_VERSION) { + downloadUpgradeMinistro(loaderParams.getString(ERROR_MESSAGE_KEY)); + return; + } + + // fatal error, show the error and quit + AlertDialog errorDialog = new AlertDialog.Builder(m_context).create(); + errorDialog.setMessage(loaderParams.getString(ERROR_MESSAGE_KEY)); + errorDialog.setButton(m_context.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + } + }); + errorDialog.show(); + return; + } + + // add all bundled Qt libs to loader params + ArrayList libs = new ArrayList(); + if (m_contextInfo.metaData.containsKey("android.app.bundled_libs_resource_id")) { + int resourceId = m_contextInfo.metaData.getInt("android.app.bundled_libs_resource_id"); + libs.addAll(prefferedAbiLibs(m_context.getResources().getStringArray(resourceId))); + } + + String libName = null; + if (m_contextInfo.metaData.containsKey("android.app.lib_name")) { + libName = m_contextInfo.metaData.getString("android.app.lib_name") + "_" + preferredAbi; + loaderParams.putString(MAIN_LIBRARY_KEY, libName); //main library contains main() function + } + + loaderParams.putStringArrayList(BUNDLED_LIBRARIES_KEY, libs); + loaderParams.putInt(NECESSITAS_API_LEVEL_KEY, NECESSITAS_API_LEVEL); + + // load and start QtLoader class + DexClassLoader classLoader = new DexClassLoader(loaderParams.getString(DEX_PATH_KEY), // .jar/.apk files + m_context.getDir("outdex", Context.MODE_PRIVATE).getAbsolutePath(), // directory where optimized DEX files should be written. + loaderParams.containsKey(LIB_PATH_KEY) ? loaderParams.getString(LIB_PATH_KEY) : null, // libs folder (if exists) + m_context.getClassLoader()); // parent loader + + Class loaderClass = classLoader.loadClass(loaderParams.getString(LOADER_CLASS_NAME_KEY)); // load QtLoader class + Object qtLoader = loaderClass.newInstance(); // create an instance + Method prepareAppMethod = qtLoader.getClass().getMethod("loadApplication", + contextClassName(), + ClassLoader.class, + Bundle.class); + if (!(Boolean)prepareAppMethod.invoke(qtLoader, m_context, classLoader, loaderParams)) + throw new Exception(""); + + QtApplication.setQtContextDelegate(m_delegateClass, qtLoader); + + Method startAppMethod=qtLoader.getClass().getMethod("startApplication"); + if (!(Boolean)startAppMethod.invoke(qtLoader)) + throw new Exception(""); + + } catch (Exception e) { + e.printStackTrace(); + AlertDialog errorDialog = new AlertDialog.Builder(m_context).create(); + if (m_contextInfo.metaData.containsKey("android.app.fatal_error_msg")) + errorDialog.setMessage(m_contextInfo.metaData.getString("android.app.fatal_error_msg")); + else + errorDialog.setMessage("Fatal error, your application can't be started."); + + errorDialog.setButton(m_context.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + } + }); + errorDialog.show(); + } + } + + private ServiceConnection m_ministroConnection=new ServiceConnection() { + private IMinistro m_service = null; + @Override + public void onServiceConnected(ComponentName name, IBinder service) + { + m_service = IMinistro.Stub.asInterface(service); + try { + if (m_service != null) { + Bundle parameters = new Bundle(); + parameters.putStringArray(REQUIRED_MODULES_KEY, (String[]) m_qtLibs.toArray()); + parameters.putString(APPLICATION_TITLE_KEY, getTitle()); + parameters.putInt(MINIMUM_MINISTRO_API_KEY, MINISTRO_API_LEVEL); + parameters.putInt(MINIMUM_QT_VERSION_KEY, QT_VERSION); + parameters.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES); + if (APPLICATION_PARAMETERS != null) + parameters.putString(APPLICATION_PARAMETERS_KEY, APPLICATION_PARAMETERS); + parameters.putStringArray(SOURCES_KEY, m_sources); + parameters.putString(REPOSITORY_KEY, m_repository); + if (QT_ANDROID_THEMES != null) + parameters.putStringArray(ANDROID_THEMES_KEY, QT_ANDROID_THEMES); + m_service.requestLoader(m_ministroCallback, parameters); + } + } catch (RemoteException e) { + e.printStackTrace(); + } + } + + private IMinistroCallback m_ministroCallback = new IMinistroCallback.Stub() { + // this function is called back by Ministro. + @Override + public void loaderReady(final Bundle loaderParams) throws RemoteException { + runOnUiThread(new Runnable() { + @Override + public void run() { + m_context.unbindService(m_ministroConnection); + loadApplication(loaderParams); + } + }); + } + }; + + @Override + public void onServiceDisconnected(ComponentName name) { + m_service = null; + } + }; + + protected void ministroNotFound() + { + AlertDialog errorDialog = new AlertDialog.Builder(m_context).create(); + + if (m_contextInfo.metaData.containsKey("android.app.ministro_not_found_msg")) + errorDialog.setMessage(m_contextInfo.metaData.getString("android.app.ministro_not_found_msg")); + else + errorDialog.setMessage("Can't find Ministro service.\nThe application can't start."); + + errorDialog.setButton(m_context.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + } + }); + errorDialog.show(); + } + + public void startApp(final boolean firstStart) + { + try { + if (m_contextInfo.metaData.containsKey("android.app.qt_sources_resource_id")) { + int resourceId = m_contextInfo.metaData.getInt("android.app.qt_sources_resource_id"); + m_sources = m_context.getResources().getStringArray(resourceId); + } + + if (m_contextInfo.metaData.containsKey("android.app.repository")) + m_repository = m_contextInfo.metaData.getString("android.app.repository"); + + if (m_contextInfo.metaData.containsKey("android.app.qt_libs_resource_id")) { + int resourceId = m_contextInfo.metaData.getInt("android.app.qt_libs_resource_id"); + m_qtLibs = prefferedAbiLibs(m_context.getResources().getStringArray(resourceId)); + } + + if (m_contextInfo.metaData.containsKey("android.app.use_local_qt_libs") + && m_contextInfo.metaData.getInt("android.app.use_local_qt_libs") == 1) { + ArrayList libraryList = new ArrayList(); + + boolean apkDeployFromSystem = false; + String apkPath = m_context.getApplicationInfo().publicSourceDir; + File apkFile = new File(apkPath); + if (apkFile.exists() && Arrays.asList(SYSTEM_APP_PATHS).contains(apkFile.getParentFile().getAbsolutePath() + "/")) + apkDeployFromSystem = true; + + String libsDir = null; + String bundledLibsDir = null; + if (apkDeployFromSystem) { + String systemLibsPrefix = SYSTEM_LIB_PATH; + if (m_contextInfo.metaData.containsKey("android.app.system_libs_prefix")) { + systemLibsPrefix = m_contextInfo.metaData.getString("android.app.system_libs_prefix"); + } else { + Log.e(QtApplication.QtTAG, "It looks like app deployed as system app. " + + "It may be necessary to specify path to system lib directory using " + + "android.app.system_libs_prefix metadata variable in your AndroidManifest.xml"); + Log.e(QtApplication.QtTAG, "Using " + SYSTEM_LIB_PATH + " as default path"); + } + File systemLibraryDir = new File(systemLibsPrefix); + if (systemLibraryDir.exists() && systemLibraryDir.isDirectory() && systemLibraryDir.list().length > 0) + libsDir = systemLibsPrefix; + } else { + String nativeLibraryPrefix = m_context.getApplicationInfo().nativeLibraryDir + "/"; + File nativeLibraryDir = new File(nativeLibraryPrefix); + if (nativeLibraryDir.exists() && nativeLibraryDir.isDirectory() && nativeLibraryDir.list().length > 0) { + libsDir = nativeLibraryPrefix; + bundledLibsDir = nativeLibraryPrefix; + } + + } + + if (apkDeployFromSystem && libsDir == null) + throw new Exception(""); + + + if (m_qtLibs != null) { + String libPrefix = libsDir + "lib"; + for (String lib : m_qtLibs) + libraryList.add(libPrefix + lib + ".so"); + } + + if (m_contextInfo.metaData.containsKey("android.app.bundle_local_qt_libs") + && m_contextInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) { + int resourceId = m_contextInfo.metaData.getInt("android.app.load_local_libs_resource_id"); + for (String libs : prefferedAbiLibs(m_context.getResources().getStringArray(resourceId))) { + for (String lib : libs.split(":")) { + if (!lib.isEmpty()) + libraryList.add(libsDir + lib); + } + } + if (bundledLibsDir != null) + ENVIRONMENT_VARIABLES += "\tQT_BUNDLED_LIBS_PATH=" + bundledLibsDir; + } + + Bundle loaderParams = new Bundle(); + loaderParams.putInt(ERROR_CODE_KEY, 0); + loaderParams.putString(DEX_PATH_KEY, new String()); + loaderParams.putString(LOADER_CLASS_NAME_KEY, loaderClassName()); + if (m_contextInfo.metaData.containsKey("android.app.static_init_classes")) { + loaderParams.putStringArray(STATIC_INIT_CLASSES_KEY, + m_contextInfo.metaData.getString("android.app.static_init_classes").split(":")); + } + loaderParams.putStringArrayList(NATIVE_LIBRARIES_KEY, libraryList); + + + String themePath = m_context.getApplicationInfo().dataDir + "/qt-reserved-files/android-style/"; + String stylePath = themePath + m_displayDensity + "/"; + + String extractOption = "default"; + if (m_contextInfo.metaData.containsKey("android.app.extract_android_style")) { + extractOption = m_contextInfo.metaData.getString("android.app.extract_android_style"); + if (!extractOption.equals("default") && !extractOption.equals("full") && !extractOption.equals("minimal") && !extractOption.equals("none")) { + Log.e(QtApplication.QtTAG, "Invalid extract_android_style option \"" + extractOption + "\", defaulting to \"default\""); + extractOption = "default"; + } + } + + // QTBUG-69810: The extraction code will trigger compatibility warnings on Android SDK version >= 28 + // when the target SDK version is set to something lower then 28, so default to "none" and issue a warning + // if that is the case. + if (extractOption.equals("default")) { + final int targetSdkVersion = m_context.getApplicationInfo().targetSdkVersion; + if (targetSdkVersion < 28 && Build.VERSION.SDK_INT >= 28) { + Log.e(QtApplication.QtTAG, "extract_android_style option set to \"none\" when targetSdkVersion is less then 28"); + extractOption = "none"; + } + } + + if (!(new File(stylePath)).exists() && !extractOption.equals("none")) { + loaderParams.putString(EXTRACT_STYLE_KEY, stylePath); + loaderParams.putBoolean(EXTRACT_STYLE_MINIMAL_KEY, extractOption.equals("minimal")); + } + + if (extractOption.equals("full")) + ENVIRONMENT_VARIABLES += "\tQT_USE_ANDROID_NATIVE_STYLE=1"; + + ENVIRONMENT_VARIABLES += "\tMINISTRO_ANDROID_STYLE_PATH=" + stylePath + + "\tQT_ANDROID_THEMES_ROOT_PATH=" + themePath; + + loaderParams.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES); + + String appParams = null; + if (APPLICATION_PARAMETERS != null) + appParams = APPLICATION_PARAMETERS; + + Intent intent = getIntent(); + if (intent != null) { + String parameters = intent.getStringExtra("applicationArguments"); + if (parameters != null) + if (appParams == null) + appParams = parameters; + else + appParams += '\t' + parameters; + } + + if (m_contextInfo.metaData.containsKey("android.app.arguments")) { + String parameters = m_contextInfo.metaData.getString("android.app.arguments"); + if (appParams == null) + appParams = parameters; + else + appParams += '\t' + parameters; + } + + if (appParams != null) + loaderParams.putString(APPLICATION_PARAMETERS_KEY, appParams.replace(' ', '\t').trim()); + + loadApplication(loaderParams); + return; + } + + try { + if (!m_context.bindService(new Intent(org.kde.necessitas.ministro.IMinistro.class.getCanonicalName()), + m_ministroConnection, + Context.BIND_AUTO_CREATE)) { + throw new SecurityException(""); + } + } catch (Exception e) { + if (firstStart) { + String msg = "This application requires Ministro service. Would you like to install it?"; + if (m_contextInfo.metaData.containsKey("android.app.ministro_needed_msg")) + msg = m_contextInfo.metaData.getString("android.app.ministro_needed_msg"); + downloadUpgradeMinistro(msg); + } else { + ministroNotFound(); + } + } + } catch (Exception e) { + Log.e(QtApplication.QtTAG, "Can't create main activity", e); + } + } +} diff --git a/src/android/java/src/org/qtproject/qt/android/bindings/QtService.java b/src/android/java/src/org/qtproject/qt/android/bindings/QtService.java new file mode 100644 index 0000000000..cb24d1f541 --- /dev/null +++ b/src/android/java/src/org/qtproject/qt/android/bindings/QtService.java @@ -0,0 +1,156 @@ +/* + Copyright (c) 2016, BogDan Vatra + Contact: http://www.qt.io/licensing/ + + Commercial License Usage + Licensees holding valid commercial Qt licenses may use this file in + accordance with the commercial license agreement provided with the + Software or, alternatively, in accordance with the terms contained in + a written agreement between you and The Qt Company. For licensing terms + and conditions see http://www.qt.io/terms-conditions. For further + information use the contact form at http://www.qt.io/contact-us. + + BSD License Usage + Alternatively, this file may be used under the BSD license as follows: + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package org.qtproject.qt.android.bindings; + +import android.app.Service; +import android.content.Intent; +import android.content.res.Configuration; +import android.os.IBinder; + +public class QtService extends Service +{ + QtServiceLoader m_loader = new QtServiceLoader(this); + + + /////////////////////////// forward all notifications //////////////////////////// + /////////////////////////// Super class calls //////////////////////////////////// + /////////////// PLEASE DO NOT CHANGE THE FOLLOWING CODE ////////////////////////// + ////////////////////////////////////////////////////////////////////////////////// + protected void onCreateHook() { + m_loader.onCreate(); + } + @Override + public void onCreate() + { + super.onCreate(); + onCreateHook(); + } + //--------------------------------------------------------------------------- + + @Override + public void onDestroy() + { + super.onDestroy(); + QtApplication.invokeDelegate(); + } + //--------------------------------------------------------------------------- + + @Override + public IBinder onBind(Intent intent) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(intent); + if (res.invoked) + return (IBinder)res.methodReturns; + else + return null; + } + //--------------------------------------------------------------------------- + + @Override + public void onConfigurationChanged(Configuration newConfig) + { + if (!QtApplication.invokeDelegate(newConfig).invoked) + super.onConfigurationChanged(newConfig); + } + public void super_onConfigurationChanged(Configuration newConfig) + { + super.onConfigurationChanged(newConfig); + } + //--------------------------------------------------------------------------- + + @Override + public void onLowMemory() + { + if (!QtApplication.invokeDelegate().invoked) + super.onLowMemory(); + } + //--------------------------------------------------------------------------- + + @Override + public int onStartCommand(Intent intent, int flags, int startId) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(intent, flags, startId); + if (res.invoked) + return (Integer) res.methodReturns; + else + return super.onStartCommand(intent, flags, startId); + } + public int super_onStartCommand(Intent intent, int flags, int startId) + { + return super.onStartCommand(intent, flags, startId); + } + //--------------------------------------------------------------------------- + + @Override + public void onTaskRemoved(Intent rootIntent) + { + if (!QtApplication.invokeDelegate(rootIntent).invoked) + super.onTaskRemoved(rootIntent); + } + public void super_onTaskRemoved(Intent rootIntent) + { + super.onTaskRemoved(rootIntent); + } + //--------------------------------------------------------------------------- + + @Override + public void onTrimMemory(int level) + { + if (!QtApplication.invokeDelegate(level).invoked) + super.onTrimMemory(level); + } + public void super_onTrimMemory(int level) + { + super.onTrimMemory(level); + } + //--------------------------------------------------------------------------- + + @Override + public boolean onUnbind(Intent intent) + { + QtApplication.InvokeResult res = QtApplication.invokeDelegate(intent); + if (res.invoked) + return (Boolean) res.methodReturns; + else + return super.onUnbind(intent); + } + public boolean super_onUnbind(Intent intent) + { + return super.onUnbind(intent); + } + //--------------------------------------------------------------------------- +} diff --git a/src/android/java/src/org/qtproject/qt/android/bindings/QtServiceLoader.java b/src/android/java/src/org/qtproject/qt/android/bindings/QtServiceLoader.java new file mode 100644 index 0000000000..f0606a4d9b --- /dev/null +++ b/src/android/java/src/org/qtproject/qt/android/bindings/QtServiceLoader.java @@ -0,0 +1,80 @@ +/* + Copyright (c) 2016, BogDan Vatra + Contact: http://www.qt.io/licensing/ + + Commercial License Usage + Licensees holding valid commercial Qt licenses may use this file in + accordance with the commercial license agreement provided with the + Software or, alternatively, in accordance with the terms contained in + a written agreement between you and The Qt Company. For licensing terms + and conditions see http://www.qt.io/terms-conditions. For further + information use the contact form at http://www.qt.io/contact-us. + + BSD License Usage + Alternatively, this file may be used under the BSD license as follows: + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package org.qtproject.qt.android.bindings; + +import android.os.Bundle; +import android.content.ComponentName; +import android.content.pm.PackageManager; + +public class QtServiceLoader extends QtLoader { + QtService m_service; + QtServiceLoader(QtService service) { + super(service, QtService.class); + m_service = service; + } + + public void onCreate() { + try { + m_contextInfo = m_service.getPackageManager().getServiceInfo(new ComponentName(m_service, m_service.getClass()), PackageManager.GET_META_DATA); + } catch (Exception e) { + e.printStackTrace(); + m_service.stopSelf(); + return; + } + + if (QtApplication.m_delegateObject != null && QtApplication.onCreate != null) { + Bundle bundle = null; + QtApplication.invokeDelegateMethod(QtApplication.onCreate, bundle); + } + startApp(true); + } + + @Override + protected void finish() { + m_service.stopSelf(); + } + + @Override + protected String loaderClassName() { + return "org.qtproject.qt.android.QtServiceDelegate"; + } + + @Override + protected Class contextClassName() { + return android.app.Service.class; + } +} diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java deleted file mode 100644 index 978a2c221e..0000000000 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java +++ /dev/null @@ -1,1119 +0,0 @@ -/* - Copyright (c) 2016, BogDan Vatra - Contact: http://www.qt.io/licensing/ - - Commercial License Usage - Licensees holding valid commercial Qt licenses may use this file in - accordance with the commercial license agreement provided with the - Software or, alternatively, in accordance with the terms contained in - a written agreement between you and The Qt Company. For licensing terms - and conditions see http://www.qt.io/terms-conditions. For further - information use the contact form at http://www.qt.io/contact-us. - - BSD License Usage - Alternatively, this file may be used under the BSD license as follows: - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package org.qtproject.qt5.android.bindings; - -import android.app.Activity; -import android.app.Dialog; -import android.app.Fragment; -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.content.res.Resources.Theme; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.os.Build; -import android.os.Bundle; -import android.util.AttributeSet; -import android.view.ActionMode; -import android.view.ActionMode.Callback; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.View; -import android.view.WindowManager.LayoutParams; -import android.view.accessibility.AccessibilityEvent; - -import org.qtproject.qt5.android.QtNative; - -public class QtActivity extends Activity -{ - public String APPLICATION_PARAMETERS = null; // use this variable to pass any parameters to your application, - // the parameters must not contain any white spaces - // and must be separated with "\t" - // e.g "-param1\t-param2=value2\t-param3\tvalue3" - - public String ENVIRONMENT_VARIABLES = "QT_USE_ANDROID_NATIVE_DIALOGS=1"; - // use this variable to add any environment variables to your application. - // the env vars must be separated with "\t" - // e.g. "ENV_VAR1=1\tENV_VAR2=2\t" - // Currently the following vars are used by the android plugin: - // * QT_USE_ANDROID_NATIVE_DIALOGS - 1 to use the android native dialogs. - - public String[] QT_ANDROID_THEMES = null; // A list with all themes that your application want to use. - // The name of the theme must be the same with any theme from - // http://developer.android.com/reference/android/R.style.html - // The most used themes are: - // * "Theme" - (fallback) check http://developer.android.com/reference/android/R.style.html#Theme - // * "Theme_Black" - check http://developer.android.com/reference/android/R.style.html#Theme_Black - // * "Theme_Light" - (default for API <=10) check http://developer.android.com/reference/android/R.style.html#Theme_Light - // * "Theme_Holo" - check http://developer.android.com/reference/android/R.style.html#Theme_Holo - // * "Theme_Holo_Light" - (default for API 11-13) check http://developer.android.com/reference/android/R.style.html#Theme_Holo_Light - // * "Theme_DeviceDefault" - check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault - // * "Theme_DeviceDefault_Light" - (default for API 14+) check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault_Light - - public String QT_ANDROID_DEFAULT_THEME = null; // sets the default theme. - - private QtActivityLoader m_loader; - public QtActivity() - { - m_loader = new QtActivityLoader(this); - QT_ANDROID_THEMES = new String[] {"Theme_Holo_Light"}; - QT_ANDROID_DEFAULT_THEME = "Theme_Holo_Light"; - } - - - /////////////////////////// forward all notifications //////////////////////////// - /////////////////////////// Super class calls //////////////////////////////////// - /////////////// PLEASE DO NOT CHANGE THE FOLLOWING CODE ////////////////////////// - ////////////////////////////////////////////////////////////////////////////////// - - @Override - public boolean dispatchKeyEvent(KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.dispatchKeyEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchKeyEvent, event); - else - return super.dispatchKeyEvent(event); - } - public boolean super_dispatchKeyEvent(KeyEvent event) - { - return super.dispatchKeyEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.dispatchPopulateAccessibilityEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchPopulateAccessibilityEvent, event); - else - return super.dispatchPopulateAccessibilityEvent(event); - } - public boolean super_dispatchPopulateAccessibilityEvent(AccessibilityEvent event) - { - return super.dispatchPopulateAccessibilityEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) - { - if (QtApplication.m_delegateObject != null && QtApplication.dispatchTouchEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchTouchEvent, ev); - else - return super.dispatchTouchEvent(ev); - } - public boolean super_dispatchTouchEvent(MotionEvent event) - { - return super.dispatchTouchEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public boolean dispatchTrackballEvent(MotionEvent ev) - { - if (QtApplication.m_delegateObject != null && QtApplication.dispatchTrackballEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchTrackballEvent, ev); - else - return super.dispatchTrackballEvent(ev); - } - public boolean super_dispatchTrackballEvent(MotionEvent event) - { - return super.dispatchTrackballEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) - { - - if (QtApplication.m_delegateObject != null && QtApplication.onActivityResult != null) { - QtApplication.invokeDelegateMethod(QtApplication.onActivityResult, requestCode, resultCode, data); - return; - } - if (requestCode == QtLoader.MINISTRO_INSTALL_REQUEST_CODE) - m_loader.startApp(false); - super.onActivityResult(requestCode, resultCode, data); - } - public void super_onActivityResult(int requestCode, int resultCode, Intent data) - { - super.onActivityResult(requestCode, resultCode, data); - } - //--------------------------------------------------------------------------- - - @Override - protected void onApplyThemeResource(Theme theme, int resid, boolean first) - { - if (!QtApplication.invokeDelegate(theme, resid, first).invoked) - super.onApplyThemeResource(theme, resid, first); - } - public void super_onApplyThemeResource(Theme theme, int resid, boolean first) - { - super.onApplyThemeResource(theme, resid, first); - } - //--------------------------------------------------------------------------- - - - @Override - protected void onChildTitleChanged(Activity childActivity, CharSequence title) - { - if (!QtApplication.invokeDelegate(childActivity, title).invoked) - super.onChildTitleChanged(childActivity, title); - } - public void super_onChildTitleChanged(Activity childActivity, CharSequence title) - { - super.onChildTitleChanged(childActivity, title); - } - //--------------------------------------------------------------------------- - - @Override - public void onConfigurationChanged(Configuration newConfig) - { - if (!QtApplication.invokeDelegate(newConfig).invoked) - super.onConfigurationChanged(newConfig); - } - public void super_onConfigurationChanged(Configuration newConfig) - { - super.onConfigurationChanged(newConfig); - } - //--------------------------------------------------------------------------- - - @Override - public void onContentChanged() - { - if (!QtApplication.invokeDelegate().invoked) - super.onContentChanged(); - } - public void super_onContentChanged() - { - super.onContentChanged(); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onContextItemSelected(MenuItem item) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(item); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onContextItemSelected(item); - } - public boolean super_onContextItemSelected(MenuItem item) - { - return super.onContextItemSelected(item); - } - //--------------------------------------------------------------------------- - - @Override - public void onContextMenuClosed(Menu menu) - { - if (!QtApplication.invokeDelegate(menu).invoked) - super.onContextMenuClosed(menu); - } - public void super_onContextMenuClosed(Menu menu) - { - super.onContextMenuClosed(menu); - } - //--------------------------------------------------------------------------- - - protected void onCreateHook(Bundle savedInstanceState) { - m_loader.APPLICATION_PARAMETERS = APPLICATION_PARAMETERS; - m_loader.ENVIRONMENT_VARIABLES = ENVIRONMENT_VARIABLES; - m_loader.QT_ANDROID_THEMES = QT_ANDROID_THEMES; - m_loader.QT_ANDROID_DEFAULT_THEME = QT_ANDROID_DEFAULT_THEME; - m_loader.onCreate(savedInstanceState); - } - - @Override - public void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - onCreateHook(savedInstanceState); - } - //--------------------------------------------------------------------------- - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) - { - if (!QtApplication.invokeDelegate(menu, v, menuInfo).invoked) - super.onCreateContextMenu(menu, v, menuInfo); - } - public void super_onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) - { - super.onCreateContextMenu(menu, v, menuInfo); - } - //--------------------------------------------------------------------------- - - @Override - public CharSequence onCreateDescription() - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(); - if (res.invoked) - return (CharSequence)res.methodReturns; - else - return super.onCreateDescription(); - } - public CharSequence super_onCreateDescription() - { - return super.onCreateDescription(); - } - //--------------------------------------------------------------------------- - - @Override - protected Dialog onCreateDialog(int id) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(id); - if (res.invoked) - return (Dialog)res.methodReturns; - else - return super.onCreateDialog(id); - } - public Dialog super_onCreateDialog(int id) - { - return super.onCreateDialog(id); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onCreateOptionsMenu(Menu menu) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(menu); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onCreateOptionsMenu(menu); - } - public boolean super_onCreateOptionsMenu(Menu menu) - { - return super.onCreateOptionsMenu(menu); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onCreatePanelMenu(int featureId, Menu menu) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId, menu); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onCreatePanelMenu(featureId, menu); - } - public boolean super_onCreatePanelMenu(int featureId, Menu menu) - { - return super.onCreatePanelMenu(featureId, menu); - } - //--------------------------------------------------------------------------- - - - @Override - public View onCreatePanelView(int featureId) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId); - if (res.invoked) - return (View)res.methodReturns; - else - return super.onCreatePanelView(featureId); - } - public View super_onCreatePanelView(int featureId) - { - return super.onCreatePanelView(featureId); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onCreateThumbnail(Bitmap outBitmap, Canvas canvas) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(outBitmap, canvas); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onCreateThumbnail(outBitmap, canvas); - } - public boolean super_onCreateThumbnail(Bitmap outBitmap, Canvas canvas) - { - return super.onCreateThumbnail(outBitmap, canvas); - } - //--------------------------------------------------------------------------- - - @Override - public View onCreateView(String name, Context context, AttributeSet attrs) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(name, context, attrs); - if (res.invoked) - return (View)res.methodReturns; - else - return super.onCreateView(name, context, attrs); - } - public View super_onCreateView(String name, Context context, AttributeSet attrs) - { - return super.onCreateView(name, context, attrs); - } - //--------------------------------------------------------------------------- - - @Override - protected void onDestroy() - { - super.onDestroy(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onKeyDown != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyDown, keyCode, event); - else - return super.onKeyDown(keyCode, event); - } - public boolean super_onKeyDown(int keyCode, KeyEvent event) - { - return super.onKeyDown(keyCode, event); - } - //--------------------------------------------------------------------------- - - - @Override - public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onKeyMultiple != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyMultiple, keyCode, repeatCount, event); - else - return super.onKeyMultiple(keyCode, repeatCount, event); - } - public boolean super_onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) - { - return super.onKeyMultiple(keyCode, repeatCount, event); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onKeyUp != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyUp, keyCode, event); - else - return super.onKeyUp(keyCode, event); - } - public boolean super_onKeyUp(int keyCode, KeyEvent event) - { - return super.onKeyUp(keyCode, event); - } - //--------------------------------------------------------------------------- - - @Override - public void onLowMemory() - { - if (!QtApplication.invokeDelegate().invoked) - super.onLowMemory(); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId, item); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onMenuItemSelected(featureId, item); - } - public boolean super_onMenuItemSelected(int featureId, MenuItem item) - { - return super.onMenuItemSelected(featureId, item); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onMenuOpened(int featureId, Menu menu) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId, menu); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onMenuOpened(featureId, menu); - } - public boolean super_onMenuOpened(int featureId, Menu menu) - { - return super.onMenuOpened(featureId, menu); - } - //--------------------------------------------------------------------------- - - @Override - protected void onNewIntent(Intent intent) - { - if (!QtApplication.invokeDelegate(intent).invoked) - super.onNewIntent(intent); - } - public void super_onNewIntent(Intent intent) - { - super.onNewIntent(intent); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onOptionsItemSelected(MenuItem item) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(item); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onOptionsItemSelected(item); - } - public boolean super_onOptionsItemSelected(MenuItem item) - { - return super.onOptionsItemSelected(item); - } - //--------------------------------------------------------------------------- - - @Override - public void onOptionsMenuClosed(Menu menu) - { - if (!QtApplication.invokeDelegate(menu).invoked) - super.onOptionsMenuClosed(menu); - } - public void super_onOptionsMenuClosed(Menu menu) - { - super.onOptionsMenuClosed(menu); - } - //--------------------------------------------------------------------------- - - @Override - public void onPanelClosed(int featureId, Menu menu) - { - if (!QtApplication.invokeDelegate(featureId, menu).invoked) - super.onPanelClosed(featureId, menu); - } - public void super_onPanelClosed(int featureId, Menu menu) - { - super.onPanelClosed(featureId, menu); - } - //--------------------------------------------------------------------------- - - @Override - protected void onPause() - { - super.onPause(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onPostCreate(Bundle savedInstanceState) - { - super.onPostCreate(savedInstanceState); - QtApplication.invokeDelegate(savedInstanceState); - } - //--------------------------------------------------------------------------- - - @Override - protected void onPostResume() - { - super.onPostResume(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onPrepareDialog(int id, Dialog dialog) - { - if (!QtApplication.invokeDelegate(id, dialog).invoked) - super.onPrepareDialog(id, dialog); - } - public void super_onPrepareDialog(int id, Dialog dialog) - { - super.onPrepareDialog(id, dialog); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onPrepareOptionsMenu(Menu menu) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(menu); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onPrepareOptionsMenu(menu); - } - public boolean super_onPrepareOptionsMenu(Menu menu) - { - return super.onPrepareOptionsMenu(menu); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onPreparePanel(int featureId, View view, Menu menu) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId, view, menu); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onPreparePanel(featureId, view, menu); - } - public boolean super_onPreparePanel(int featureId, View view, Menu menu) - { - return super.onPreparePanel(featureId, view, menu); - } - //--------------------------------------------------------------------------- - - @Override - protected void onRestart() - { - super.onRestart(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) - { - if (!QtApplication.invokeDelegate(savedInstanceState).invoked) - super.onRestoreInstanceState(savedInstanceState); - } - public void super_onRestoreInstanceState(Bundle savedInstanceState) - { - super.onRestoreInstanceState(savedInstanceState); - } - //--------------------------------------------------------------------------- - - @Override - protected void onResume() - { - super.onResume(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - public Object onRetainNonConfigurationInstance() - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(); - if (res.invoked) - return res.methodReturns; - else - return super.onRetainNonConfigurationInstance(); - } - public Object super_onRetainNonConfigurationInstance() - { - return super.onRetainNonConfigurationInstance(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onSaveInstanceState(Bundle outState) - { - if (!QtApplication.invokeDelegate(outState).invoked) - super.onSaveInstanceState(outState); - } - public void super_onSaveInstanceState(Bundle outState) - { - super.onSaveInstanceState(outState); - - } - //--------------------------------------------------------------------------- - - @Override - public boolean onSearchRequested() - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onSearchRequested(); - } - public boolean super_onSearchRequested() - { - return super.onSearchRequested(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onStart() - { - super.onStart(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onStop() - { - super.onStop(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onTitleChanged(CharSequence title, int color) - { - if (!QtApplication.invokeDelegate(title, color).invoked) - super.onTitleChanged(title, color); - } - public void super_onTitleChanged(CharSequence title, int color) - { - super.onTitleChanged(title, color); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onTouchEvent(MotionEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onTouchEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onTouchEvent, event); - else - return super.onTouchEvent(event); - } - public boolean super_onTouchEvent(MotionEvent event) - { - return super.onTouchEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onTrackballEvent(MotionEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onTrackballEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onTrackballEvent, event); - else - return super.onTrackballEvent(event); - } - public boolean super_onTrackballEvent(MotionEvent event) - { - return super.onTrackballEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public void onUserInteraction() - { - if (!QtApplication.invokeDelegate().invoked) - super.onUserInteraction(); - } - public void super_onUserInteraction() - { - super.onUserInteraction(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onUserLeaveHint() - { - if (!QtApplication.invokeDelegate().invoked) - super.onUserLeaveHint(); - } - public void super_onUserLeaveHint() - { - super.onUserLeaveHint(); - } - //--------------------------------------------------------------------------- - - @Override - public void onWindowAttributesChanged(LayoutParams params) - { - if (!QtApplication.invokeDelegate(params).invoked) - super.onWindowAttributesChanged(params); - } - public void super_onWindowAttributesChanged(LayoutParams params) - { - super.onWindowAttributesChanged(params); - } - //--------------------------------------------------------------------------- - - @Override - public void onWindowFocusChanged(boolean hasFocus) - { - if (!QtApplication.invokeDelegate(hasFocus).invoked) - super.onWindowFocusChanged(hasFocus); - } - public void super_onWindowFocusChanged(boolean hasFocus) - { - super.onWindowFocusChanged(hasFocus); - } - //--------------------------------------------------------------------------- - - //////////////// Activity API 5 ///////////// -//@ANDROID-5 - @Override - public void onAttachedToWindow() - { - if (!QtApplication.invokeDelegate().invoked) - super.onAttachedToWindow(); - } - public void super_onAttachedToWindow() - { - super.onAttachedToWindow(); - } - //--------------------------------------------------------------------------- - - @Override - public void onBackPressed() - { - if (!QtApplication.invokeDelegate().invoked) - super.onBackPressed(); - } - public void super_onBackPressed() - { - super.onBackPressed(); - } - //--------------------------------------------------------------------------- - - @Override - public void onDetachedFromWindow() - { - if (!QtApplication.invokeDelegate().invoked) - super.onDetachedFromWindow(); - } - public void super_onDetachedFromWindow() - { - super.onDetachedFromWindow(); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onKeyLongPress(int keyCode, KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onKeyLongPress != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyLongPress, keyCode, event); - else - return super.onKeyLongPress(keyCode, event); - } - public boolean super_onKeyLongPress(int keyCode, KeyEvent event) - { - return super.onKeyLongPress(keyCode, event); - } - //--------------------------------------------------------------------------- -//@ANDROID-5 - -//////////////// Activity API 8 ///////////// -//@ANDROID-8 -@Override - protected Dialog onCreateDialog(int id, Bundle args) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(id, args); - if (res.invoked) - return (Dialog)res.methodReturns; - else - return super.onCreateDialog(id, args); - } - public Dialog super_onCreateDialog(int id, Bundle args) - { - return super.onCreateDialog(id, args); - } - //--------------------------------------------------------------------------- - - @Override - protected void onPrepareDialog(int id, Dialog dialog, Bundle args) - { - if (!QtApplication.invokeDelegate(id, dialog, args).invoked) - super.onPrepareDialog(id, dialog, args); - } - public void super_onPrepareDialog(int id, Dialog dialog, Bundle args) - { - super.onPrepareDialog(id, dialog, args); - } - //--------------------------------------------------------------------------- -//@ANDROID-8 - //////////////// Activity API 11 ///////////// - -//@ANDROID-11 - @Override - public boolean dispatchKeyShortcutEvent(KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.dispatchKeyShortcutEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchKeyShortcutEvent, event); - else - return super.dispatchKeyShortcutEvent(event); - } - public boolean super_dispatchKeyShortcutEvent(KeyEvent event) - { - return super.dispatchKeyShortcutEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public void onActionModeFinished(ActionMode mode) - { - if (!QtApplication.invokeDelegate(mode).invoked) - super.onActionModeFinished(mode); - } - public void super_onActionModeFinished(ActionMode mode) - { - super.onActionModeFinished(mode); - } - //--------------------------------------------------------------------------- - - @Override - public void onActionModeStarted(ActionMode mode) - { - if (!QtApplication.invokeDelegate(mode).invoked) - super.onActionModeStarted(mode); - } - public void super_onActionModeStarted(ActionMode mode) - { - super.onActionModeStarted(mode); - } - //--------------------------------------------------------------------------- - - @Override - public void onAttachFragment(Fragment fragment) - { - if (!QtApplication.invokeDelegate(fragment).invoked) - super.onAttachFragment(fragment); - } - public void super_onAttachFragment(Fragment fragment) - { - super.onAttachFragment(fragment); - } - //--------------------------------------------------------------------------- - - @Override - public View onCreateView(View parent, String name, Context context, AttributeSet attrs) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(parent, name, context, attrs); - if (res.invoked) - return (View)res.methodReturns; - else - return super.onCreateView(parent, name, context, attrs); - } - public View super_onCreateView(View parent, String name, Context context, - AttributeSet attrs) { - return super.onCreateView(parent, name, context, attrs); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onKeyShortcut(int keyCode, KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onKeyShortcut != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyShortcut, keyCode,event); - else - return super.onKeyShortcut(keyCode, event); - } - public boolean super_onKeyShortcut(int keyCode, KeyEvent event) - { - return super.onKeyShortcut(keyCode, event); - } - //--------------------------------------------------------------------------- - - @Override - public ActionMode onWindowStartingActionMode(Callback callback) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(callback); - if (res.invoked) - return (ActionMode)res.methodReturns; - else - return super.onWindowStartingActionMode(callback); - } - public ActionMode super_onWindowStartingActionMode(Callback callback) - { - return super.onWindowStartingActionMode(callback); - } - //--------------------------------------------------------------------------- -//@ANDROID-11 - //////////////// Activity API 12 ///////////// - -//@ANDROID-12 - @Override - public boolean dispatchGenericMotionEvent(MotionEvent ev) - { - if (QtApplication.m_delegateObject != null && QtApplication.dispatchGenericMotionEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchGenericMotionEvent, ev); - else - return super.dispatchGenericMotionEvent(ev); - } - public boolean super_dispatchGenericMotionEvent(MotionEvent event) - { - return super.dispatchGenericMotionEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onGenericMotionEvent(MotionEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onGenericMotionEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onGenericMotionEvent, event); - else - return super.onGenericMotionEvent(event); - } - public boolean super_onGenericMotionEvent(MotionEvent event) - { - return super.onGenericMotionEvent(event); - } - //--------------------------------------------------------------------------- -//@ANDROID-12 - - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) - { - if (QtApplication.m_delegateObject != null && QtApplication.onRequestPermissionsResult != null) { - QtApplication.invokeDelegateMethod(QtApplication.onRequestPermissionsResult, requestCode , permissions, grantResults); - return; - } - } - - public void bringChildToBack(int id) - { - QtNative.activityDelegate().bringChildToBack(id); - } - - public void bringChildToFront(int id) - { - QtNative.activityDelegate().bringChildToFront(id); - } - - public void closeContextMenu() - { - QtNative.activityDelegate().closeContextMenu(); - } - - public void createSurface(int id, boolean onTop, int x, int y, int w, int h, int imageDepth) - { - QtNative.activityDelegate().createSurface(id, onTop, x, y, w, h, imageDepth); - } - - public void destroySurface(int id) - { - QtNative.activityDelegate().destroySurface(id); - } - - public int getSurfaceCount() - { - return QtNative.activityDelegate().getSurfaceCount(); - } - - public void hideSoftwareKeyboard() - { - QtNative.activityDelegate().hideSoftwareKeyboard(); - } - - public void hideSplashScreen() - { - QtNative.activityDelegate().hideSplashScreen(); - } - - public void hideSplashScreen(final int duration) - { - QtNative.activityDelegate().hideSplashScreen(duration); - } - - public void initializeAccessibility() - { - QtNative.activityDelegate().initializeAccessibility(); - } - - public void insertNativeView(int id, View view, int x, int y, int w, int h) - { - QtNative.activityDelegate().insertNativeView(id, view, x, y, w, h); - } - - public boolean loadApplication(Activity activity, ClassLoader classLoader, Bundle loaderParams) - { - return QtNative.activityDelegate().loadApplication(activity, classLoader, loaderParams); - } - - public void onCreatePopupMenu(Menu menu) - { - QtNative.activityDelegate().onCreatePopupMenu(menu); - } - - public void onTerminate() - { - QtNative.activityDelegate().onTerminate(); - } - - public void openContextMenu(final int x, final int y, final int w, final int h) - { - QtNative.activityDelegate().openContextMenu(x, y, w, h); - } - - public void resetOptionsMenu() - { - QtNative.activityDelegate().resetOptionsMenu(); - } - - public void resetSoftwareKeyboard() - { - QtNative.activityDelegate().resetSoftwareKeyboard(); - } - - public boolean setKeyboardVisibility(boolean visibility, long timeStamp) - { - return QtNative.activityDelegate().setKeyboardVisibility(visibility, timeStamp); - } - - public void setSurfaceGeometry(int id, int x, int y, int w, int h) - { - QtNative.activityDelegate().setSurfaceGeometry(id, x, y, w, h); - } - - public void setSystemUiVisibility(int systemUiVisibility) - { - QtNative.activityDelegate().setSystemUiVisibility(systemUiVisibility); - } - - public void showSoftwareKeyboard(final int x, final int y, final int width, - final int height, final int inputHints, - final int enterKeyType) - { - QtNative.activityDelegate().showSoftwareKeyboard(x, y, width, height, inputHints, enterKeyType); - } - - public boolean startApplication() - { - return QtNative.activityDelegate().startApplication(); - } - - public void updateFullScreen() - { - QtNative.activityDelegate().updateFullScreen(); - } - - public void updateHandles(int mode, int editX, int editY, int editButtons, - int x1, int y1, int x2, int y2, boolean rtl) - { - QtNative.activityDelegate().updateHandles(mode, editX, editY, editButtons, x1, y1, x2, y2, rtl); - } - - public void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd) - { - QtNative.activityDelegate().updateSelection(selStart, selEnd, candidatesStart, candidatesEnd); - } -} diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java deleted file mode 100644 index 9e00b14999..0000000000 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright (c) 2016, BogDan Vatra - Contact: http://www.qt-project.org/legal - - Commercial License Usage - Licensees holding valid commercial Qt licenses may use this file in - accordance with the commercial license agreement provided with the - Software or, alternatively, in accordance with the terms contained in - a written agreement between you and Digia. For licensing terms and - conditions see http://qt.digia.com/licensing. For further information - use the contact form at http://qt.digia.com/contact-us. - - BSD License Usage - Alternatively, this file may be used under the BSD license as follows: - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package org.qtproject.qt5.android.bindings; - -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.graphics.drawable.ColorDrawable; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.view.Window; - - -import java.lang.reflect.Field; - -public class QtActivityLoader extends QtLoader { - QtActivity m_activity; - - QtActivityLoader(QtActivity activity) - { - super(activity, QtActivity.class); - m_activity = activity; - } - @Override - protected void downloadUpgradeMinistro(String msg) { - AlertDialog.Builder downloadDialog = new AlertDialog.Builder(m_activity); - downloadDialog.setMessage(msg); - downloadDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - try { - Uri uri = Uri.parse("market://details?id=org.kde.necessitas.ministro"); - Intent intent = new Intent(Intent.ACTION_VIEW, uri); - m_activity.startActivityForResult(intent, MINISTRO_INSTALL_REQUEST_CODE); - } catch (Exception e) { - e.printStackTrace(); - ministroNotFound(); - } - } - }); - - downloadDialog.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - m_activity.finish(); - } - }); - downloadDialog.show(); - } - - @Override - protected String loaderClassName() { - return "org.qtproject.qt5.android.QtActivityDelegate"; - } - - @Override - protected Class contextClassName() { - return android.app.Activity.class; - } - - @Override - protected void finish() { - m_activity.finish(); - } - - @Override - protected String getTitle() { - return (String) m_activity.getTitle(); - } - - @Override - protected void runOnUiThread(Runnable run) { - m_activity.runOnUiThread(run); - } - - @Override - Intent getIntent() { - return m_activity.getIntent(); - } - - public void onCreate(Bundle savedInstanceState) { - try { - m_contextInfo = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), PackageManager.GET_META_DATA); - int theme = ((ActivityInfo)m_contextInfo).getThemeResource(); - for (Field f : Class.forName("android.R$style").getDeclaredFields()) { - if (f.getInt(null) == theme) { - QT_ANDROID_THEMES = new String[] {f.getName()}; - QT_ANDROID_DEFAULT_THEME = f.getName(); - break; - } - } - } catch (Exception e) { - e.printStackTrace(); - finish(); - return; - } - - try { - m_activity.setTheme(Class.forName("android.R$style").getDeclaredField(QT_ANDROID_DEFAULT_THEME).getInt(null)); - } catch (Exception e) { - e.printStackTrace(); - } - - m_activity.requestWindowFeature(Window.FEATURE_ACTION_BAR); - - if (QtApplication.m_delegateObject != null && QtApplication.onCreate != null) { - QtApplication.invokeDelegateMethod(QtApplication.onCreate, savedInstanceState); - return; - } - - m_displayDensity = m_activity.getResources().getDisplayMetrics().densityDpi; - - ENVIRONMENT_VARIABLES += "\tQT_ANDROID_THEME=" + QT_ANDROID_DEFAULT_THEME - + "/\tQT_ANDROID_THEME_DISPLAY_DPI=" + m_displayDensity + "\t"; - - if (null == m_activity.getLastNonConfigurationInstance()) { - if (m_contextInfo.metaData.containsKey("android.app.background_running") - && m_contextInfo.metaData.getBoolean("android.app.background_running")) { - ENVIRONMENT_VARIABLES += "QT_BLOCK_EVENT_LOOPS_WHEN_SUSPENDED=0\t"; - } else { - ENVIRONMENT_VARIABLES += "QT_BLOCK_EVENT_LOOPS_WHEN_SUSPENDED=1\t"; - } - - startApp(true); - } - } -} diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java deleted file mode 100644 index 47dcde304c..0000000000 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright (c) 2016, BogDan Vatra - Contact: http://www.qt.io/licensing/ - - Commercial License Usage - Licensees holding valid commercial Qt licenses may use this file in - accordance with the commercial license agreement provided with the - Software or, alternatively, in accordance with the terms contained in - a written agreement between you and The Qt Company. For licensing terms - and conditions see http://www.qt.io/terms-conditions. For further - information use the contact form at http://www.qt.io/contact-us. - - BSD License Usage - Alternatively, this file may be used under the BSD license as follows: - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package org.qtproject.qt5.android.bindings; - -import android.app.Application; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; - -public class QtApplication extends Application -{ - public final static String QtTAG = "Qt"; - public static Object m_delegateObject = null; - public static HashMap> m_delegateMethods= new HashMap>(); - public static Method dispatchKeyEvent = null; - public static Method dispatchPopulateAccessibilityEvent = null; - public static Method dispatchTouchEvent = null; - public static Method dispatchTrackballEvent = null; - public static Method onKeyDown = null; - public static Method onKeyMultiple = null; - public static Method onKeyUp = null; - public static Method onTouchEvent = null; - public static Method onTrackballEvent = null; - public static Method onActivityResult = null; - public static Method onCreate = null; - public static Method onKeyLongPress = null; - public static Method dispatchKeyShortcutEvent = null; - public static Method onKeyShortcut = null; - public static Method dispatchGenericMotionEvent = null; - public static Method onGenericMotionEvent = null; - public static Method onRequestPermissionsResult = null; - private static String activityClassName; - public static void setQtContextDelegate(Class clazz, Object listener) - { - m_delegateObject = listener; - activityClassName = clazz.getCanonicalName(); - - ArrayList delegateMethods = new ArrayList(); - for (Method m : listener.getClass().getMethods()) { - if (m.getDeclaringClass().getName().startsWith("org.qtproject.qt5.android")) - delegateMethods.add(m); - } - - ArrayList applicationFields = new ArrayList(); - for (Field f : QtApplication.class.getFields()) { - if (f.getDeclaringClass().getName().equals(QtApplication.class.getName())) - applicationFields.add(f); - } - - for (Method delegateMethod : delegateMethods) { - try { - clazz.getDeclaredMethod(delegateMethod.getName(), delegateMethod.getParameterTypes()); - if (QtApplication.m_delegateMethods.containsKey(delegateMethod.getName())) { - QtApplication.m_delegateMethods.get(delegateMethod.getName()).add(delegateMethod); - } else { - ArrayList delegateSet = new ArrayList(); - delegateSet.add(delegateMethod); - QtApplication.m_delegateMethods.put(delegateMethod.getName(), delegateSet); - } - for (Field applicationField:applicationFields) { - if (applicationField.getName().equals(delegateMethod.getName())) { - try { - applicationField.set(null, delegateMethod); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - @Override - public void onTerminate() { - if (m_delegateObject != null && m_delegateMethods.containsKey("onTerminate")) - invokeDelegateMethod(m_delegateMethods.get("onTerminate").get(0)); - super.onTerminate(); - } - - public static class InvokeResult - { - public boolean invoked = false; - public Object methodReturns = null; - } - - private static int stackDeep=-1; - public static InvokeResult invokeDelegate(Object... args) - { - InvokeResult result = new InvokeResult(); - if (m_delegateObject == null) - return result; - StackTraceElement[] elements = Thread.currentThread().getStackTrace(); - if (-1 == stackDeep) { - for (int it=0;it - Contact: http://www.qt.io/licensing/ - - Commercial License Usage - Licensees holding valid commercial Qt licenses may use this file in - accordance with the commercial license agreement provided with the - Software or, alternatively, in accordance with the terms contained in - a written agreement between you and The Qt Company. For licensing terms - and conditions see http://www.qt.io/terms-conditions. For further - information use the contact form at http://www.qt.io/contact-us. - - BSD License Usage - Alternatively, this file may be used under the BSD license as follows: - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package org.qtproject.qt5.android.bindings; - -import android.app.AlertDialog; -import android.content.ComponentName; -import android.content.Context; -import android.content.ContextWrapper; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.pm.ComponentInfo; -import android.os.Build; -import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; -import android.util.Log; - -import org.kde.necessitas.ministro.IMinistro; -import org.kde.necessitas.ministro.IMinistroCallback; - -import java.io.File; -import java.io.FileOutputStream; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; - -import dalvik.system.DexClassLoader; - -public abstract class QtLoader { - - public final static int MINISTRO_INSTALL_REQUEST_CODE = 0xf3ee; // request code used to know when Ministro instalation is finished - public static final int MINISTRO_API_LEVEL = 5; // Ministro api level (check IMinistro.aidl file) - public static final int NECESSITAS_API_LEVEL = 2; // Necessitas api level used by platform plugin - public static final int QT_VERSION = 0x050700; // This app requires at least Qt version 5.7.0 - - public static final String ERROR_CODE_KEY = "error.code"; - public static final String ERROR_MESSAGE_KEY = "error.message"; - public static final String DEX_PATH_KEY = "dex.path"; - public static final String LIB_PATH_KEY = "lib.path"; - public static final String LOADER_CLASS_NAME_KEY = "loader.class.name"; - public static final String NATIVE_LIBRARIES_KEY = "native.libraries"; - public static final String ENVIRONMENT_VARIABLES_KEY = "environment.variables"; - public static final String APPLICATION_PARAMETERS_KEY = "application.parameters"; - public static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries"; - public static final String MAIN_LIBRARY_KEY = "main.library"; - public static final String STATIC_INIT_CLASSES_KEY = "static.init.classes"; - public static final String NECESSITAS_API_LEVEL_KEY = "necessitas.api.level"; - public static final String EXTRACT_STYLE_KEY = "extract.android.style"; - private static final String EXTRACT_STYLE_MINIMAL_KEY = "extract.android.style.option"; - - // These parameters matter in case of deploying application as system (embedded into firmware) - public static final String SYSTEM_LIB_PATH = "/system/lib/"; - public String[] SYSTEM_APP_PATHS = {"/system/priv-app/", "/system/app/"}; - - /// Ministro server parameter keys - public static final String REQUIRED_MODULES_KEY = "required.modules"; - public static final String APPLICATION_TITLE_KEY = "application.title"; - public static final String MINIMUM_MINISTRO_API_KEY = "minimum.ministro.api"; - public static final String MINIMUM_QT_VERSION_KEY = "minimum.qt.version"; - public static final String SOURCES_KEY = "sources"; // needs MINISTRO_API_LEVEL >=3 !!! - // Use this key to specify any 3rd party sources urls - // Ministro will download these repositories into their - // own folders, check http://community.kde.org/Necessitas/Ministro - // for more details. - - public static final String REPOSITORY_KEY = "repository"; // use this key to overwrite the default ministro repsitory - public static final String ANDROID_THEMES_KEY = "android.themes"; // themes that your application uses - - public String APPLICATION_PARAMETERS = null; // use this variable to pass any parameters to your application, - // the parameters must not contain any white spaces - // and must be separated with "\t" - // e.g "-param1\t-param2=value2\t-param3\tvalue3" - - public String ENVIRONMENT_VARIABLES = "QT_USE_ANDROID_NATIVE_DIALOGS=1"; - // use this variable to add any environment variables to your application. - // the env vars must be separated with "\t" - // e.g. "ENV_VAR1=1\tENV_VAR2=2\t" - // Currently the following vars are used by the android plugin: - // * QT_USE_ANDROID_NATIVE_DIALOGS -1 to use the android native dialogs. - - public String[] QT_ANDROID_THEMES = null; // A list with all themes that your application want to use. - // The name of the theme must be the same with any theme from - // http://developer.android.com/reference/android/R.style.html - // The most used themes are: - // * "Theme" - (fallback) check http://developer.android.com/reference/android/R.style.html#Theme - // * "Theme_Black" - check http://developer.android.com/reference/android/R.style.html#Theme_Black - // * "Theme_Light" - (default for API <=10) check http://developer.android.com/reference/android/R.style.html#Theme_Light - // * "Theme_Holo" - check http://developer.android.com/reference/android/R.style.html#Theme_Holo - // * "Theme_Holo_Light" - (default for API 11-13) check http://developer.android.com/reference/android/R.style.html#Theme_Holo_Light - // * "Theme_DeviceDefault" - check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault - // * "Theme_DeviceDefault_Light" - (default for API 14+) check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault_Light - - public String QT_ANDROID_DEFAULT_THEME = null; // sets the default theme. - - public static final int INCOMPATIBLE_MINISTRO_VERSION = 1; // Incompatible Ministro version. Ministro needs to be upgraded. - - public String[] m_sources = {"https://download.qt-project.org/ministro/android/qt5/qt-5.7"}; // Make sure you are using ONLY secure locations - public String m_repository = "default"; // Overwrites the default Ministro repository - // Possible values: - // * default - Ministro default repository set with "Ministro configuration tool". - // By default the stable version is used. Only this or stable repositories should - // be used in production. - // * stable - stable repository, only this and default repositories should be used - // in production. - // * testing - testing repository, DO NOT use this repository in production, - // this repository is used to push a new release, and should be used to test your application. - // * unstable - unstable repository, DO NOT use this repository in production, - // this repository is used to push Qt snapshots. - public ArrayList m_qtLibs = null; // required qt libs - public int m_displayDensity = -1; - private ContextWrapper m_context; - protected ComponentInfo m_contextInfo; - private Class m_delegateClass; - - private static ArrayList m_fileOutputStreams = new ArrayList(); - // List of open file streams associated with files copied during installation. - - QtLoader(ContextWrapper context, Class clazz) { - m_context = context; - m_delegateClass = clazz; - } - - // Implement in subclass - protected void finish() {} - - protected String getTitle() { - return "Qt"; - } - - protected void runOnUiThread(Runnable run) { - run.run(); - } - protected void downloadUpgradeMinistro(String msg) - { - Log.e(QtApplication.QtTAG, msg); - } - - protected abstract String loaderClassName(); - protected abstract Class contextClassName(); - - Intent getIntent() - { - return null; - } - // Implement in subclass - - private final List supportedAbis = Arrays.asList(Build.SUPPORTED_ABIS); - private String preferredAbi = null; - - private ArrayList prefferedAbiLibs(String []libs) - { - HashMap> abisLibs = new HashMap<>(); - for (String lib : libs) { - String[] archLib = lib.split(";", 2); - if (preferredAbi != null && !archLib[0].equals(preferredAbi)) - continue; - if (!abisLibs.containsKey(archLib[0])) - abisLibs.put(archLib[0], new ArrayList()); - abisLibs.get(archLib[0]).add(archLib[1]); - } - - if (preferredAbi != null) { - if (abisLibs.containsKey(preferredAbi)) { - return abisLibs.get(preferredAbi); - } - return new ArrayList(); - } - - for (String abi: supportedAbis) { - if (abisLibs.containsKey(abi)) { - preferredAbi = abi; - return abisLibs.get(abi); - } - } - return new ArrayList(); - } - - // this function is used to load and start the loader - private void loadApplication(Bundle loaderParams) - { - try { - final int errorCode = loaderParams.getInt(ERROR_CODE_KEY); - if (errorCode != 0) { - if (errorCode == INCOMPATIBLE_MINISTRO_VERSION) { - downloadUpgradeMinistro(loaderParams.getString(ERROR_MESSAGE_KEY)); - return; - } - - // fatal error, show the error and quit - AlertDialog errorDialog = new AlertDialog.Builder(m_context).create(); - errorDialog.setMessage(loaderParams.getString(ERROR_MESSAGE_KEY)); - errorDialog.setButton(m_context.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - finish(); - } - }); - errorDialog.show(); - return; - } - - // add all bundled Qt libs to loader params - ArrayList libs = new ArrayList(); - if (m_contextInfo.metaData.containsKey("android.app.bundled_libs_resource_id")) { - int resourceId = m_contextInfo.metaData.getInt("android.app.bundled_libs_resource_id"); - libs.addAll(prefferedAbiLibs(m_context.getResources().getStringArray(resourceId))); - } - - String libName = null; - if (m_contextInfo.metaData.containsKey("android.app.lib_name")) { - libName = m_contextInfo.metaData.getString("android.app.lib_name") + "_" + preferredAbi; - loaderParams.putString(MAIN_LIBRARY_KEY, libName); //main library contains main() function - } - - loaderParams.putStringArrayList(BUNDLED_LIBRARIES_KEY, libs); - loaderParams.putInt(NECESSITAS_API_LEVEL_KEY, NECESSITAS_API_LEVEL); - - // load and start QtLoader class - DexClassLoader classLoader = new DexClassLoader(loaderParams.getString(DEX_PATH_KEY), // .jar/.apk files - m_context.getDir("outdex", Context.MODE_PRIVATE).getAbsolutePath(), // directory where optimized DEX files should be written. - loaderParams.containsKey(LIB_PATH_KEY) ? loaderParams.getString(LIB_PATH_KEY) : null, // libs folder (if exists) - m_context.getClassLoader()); // parent loader - - Class loaderClass = classLoader.loadClass(loaderParams.getString(LOADER_CLASS_NAME_KEY)); // load QtLoader class - Object qtLoader = loaderClass.newInstance(); // create an instance - Method prepareAppMethod = qtLoader.getClass().getMethod("loadApplication", - contextClassName(), - ClassLoader.class, - Bundle.class); - if (!(Boolean)prepareAppMethod.invoke(qtLoader, m_context, classLoader, loaderParams)) - throw new Exception(""); - - QtApplication.setQtContextDelegate(m_delegateClass, qtLoader); - - Method startAppMethod=qtLoader.getClass().getMethod("startApplication"); - if (!(Boolean)startAppMethod.invoke(qtLoader)) - throw new Exception(""); - - } catch (Exception e) { - e.printStackTrace(); - AlertDialog errorDialog = new AlertDialog.Builder(m_context).create(); - if (m_contextInfo.metaData.containsKey("android.app.fatal_error_msg")) - errorDialog.setMessage(m_contextInfo.metaData.getString("android.app.fatal_error_msg")); - else - errorDialog.setMessage("Fatal error, your application can't be started."); - - errorDialog.setButton(m_context.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - finish(); - } - }); - errorDialog.show(); - } - } - - private ServiceConnection m_ministroConnection=new ServiceConnection() { - private IMinistro m_service = null; - @Override - public void onServiceConnected(ComponentName name, IBinder service) - { - m_service = IMinistro.Stub.asInterface(service); - try { - if (m_service != null) { - Bundle parameters = new Bundle(); - parameters.putStringArray(REQUIRED_MODULES_KEY, (String[]) m_qtLibs.toArray()); - parameters.putString(APPLICATION_TITLE_KEY, getTitle()); - parameters.putInt(MINIMUM_MINISTRO_API_KEY, MINISTRO_API_LEVEL); - parameters.putInt(MINIMUM_QT_VERSION_KEY, QT_VERSION); - parameters.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES); - if (APPLICATION_PARAMETERS != null) - parameters.putString(APPLICATION_PARAMETERS_KEY, APPLICATION_PARAMETERS); - parameters.putStringArray(SOURCES_KEY, m_sources); - parameters.putString(REPOSITORY_KEY, m_repository); - if (QT_ANDROID_THEMES != null) - parameters.putStringArray(ANDROID_THEMES_KEY, QT_ANDROID_THEMES); - m_service.requestLoader(m_ministroCallback, parameters); - } - } catch (RemoteException e) { - e.printStackTrace(); - } - } - - private IMinistroCallback m_ministroCallback = new IMinistroCallback.Stub() { - // this function is called back by Ministro. - @Override - public void loaderReady(final Bundle loaderParams) throws RemoteException { - runOnUiThread(new Runnable() { - @Override - public void run() { - m_context.unbindService(m_ministroConnection); - loadApplication(loaderParams); - } - }); - } - }; - - @Override - public void onServiceDisconnected(ComponentName name) { - m_service = null; - } - }; - - protected void ministroNotFound() - { - AlertDialog errorDialog = new AlertDialog.Builder(m_context).create(); - - if (m_contextInfo.metaData.containsKey("android.app.ministro_not_found_msg")) - errorDialog.setMessage(m_contextInfo.metaData.getString("android.app.ministro_not_found_msg")); - else - errorDialog.setMessage("Can't find Ministro service.\nThe application can't start."); - - errorDialog.setButton(m_context.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - finish(); - } - }); - errorDialog.show(); - } - - public void startApp(final boolean firstStart) - { - try { - if (m_contextInfo.metaData.containsKey("android.app.qt_sources_resource_id")) { - int resourceId = m_contextInfo.metaData.getInt("android.app.qt_sources_resource_id"); - m_sources = m_context.getResources().getStringArray(resourceId); - } - - if (m_contextInfo.metaData.containsKey("android.app.repository")) - m_repository = m_contextInfo.metaData.getString("android.app.repository"); - - if (m_contextInfo.metaData.containsKey("android.app.qt_libs_resource_id")) { - int resourceId = m_contextInfo.metaData.getInt("android.app.qt_libs_resource_id"); - m_qtLibs = prefferedAbiLibs(m_context.getResources().getStringArray(resourceId)); - } - - if (m_contextInfo.metaData.containsKey("android.app.use_local_qt_libs") - && m_contextInfo.metaData.getInt("android.app.use_local_qt_libs") == 1) { - ArrayList libraryList = new ArrayList(); - - boolean apkDeployFromSystem = false; - String apkPath = m_context.getApplicationInfo().publicSourceDir; - File apkFile = new File(apkPath); - if (apkFile.exists() && Arrays.asList(SYSTEM_APP_PATHS).contains(apkFile.getParentFile().getAbsolutePath() + "/")) - apkDeployFromSystem = true; - - String libsDir = null; - String bundledLibsDir = null; - if (apkDeployFromSystem) { - String systemLibsPrefix = SYSTEM_LIB_PATH; - if (m_contextInfo.metaData.containsKey("android.app.system_libs_prefix")) { - systemLibsPrefix = m_contextInfo.metaData.getString("android.app.system_libs_prefix"); - } else { - Log.e(QtApplication.QtTAG, "It looks like app deployed as system app. " - + "It may be necessary to specify path to system lib directory using " - + "android.app.system_libs_prefix metadata variable in your AndroidManifest.xml"); - Log.e(QtApplication.QtTAG, "Using " + SYSTEM_LIB_PATH + " as default path"); - } - File systemLibraryDir = new File(systemLibsPrefix); - if (systemLibraryDir.exists() && systemLibraryDir.isDirectory() && systemLibraryDir.list().length > 0) - libsDir = systemLibsPrefix; - } else { - String nativeLibraryPrefix = m_context.getApplicationInfo().nativeLibraryDir + "/"; - File nativeLibraryDir = new File(nativeLibraryPrefix); - if (nativeLibraryDir.exists() && nativeLibraryDir.isDirectory() && nativeLibraryDir.list().length > 0) { - libsDir = nativeLibraryPrefix; - bundledLibsDir = nativeLibraryPrefix; - } - - } - - if (apkDeployFromSystem && libsDir == null) - throw new Exception(""); - - - if (m_qtLibs != null) { - String libPrefix = libsDir + "lib"; - for (String lib : m_qtLibs) - libraryList.add(libPrefix + lib + ".so"); - } - - if (m_contextInfo.metaData.containsKey("android.app.bundle_local_qt_libs") - && m_contextInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) { - int resourceId = m_contextInfo.metaData.getInt("android.app.load_local_libs_resource_id"); - for (String libs : prefferedAbiLibs(m_context.getResources().getStringArray(resourceId))) { - for (String lib : libs.split(":")) { - if (!lib.isEmpty()) - libraryList.add(libsDir + lib); - } - } - if (bundledLibsDir != null) - ENVIRONMENT_VARIABLES += "\tQT_BUNDLED_LIBS_PATH=" + bundledLibsDir; - } - - Bundle loaderParams = new Bundle(); - loaderParams.putInt(ERROR_CODE_KEY, 0); - loaderParams.putString(DEX_PATH_KEY, new String()); - loaderParams.putString(LOADER_CLASS_NAME_KEY, loaderClassName()); - if (m_contextInfo.metaData.containsKey("android.app.static_init_classes")) { - loaderParams.putStringArray(STATIC_INIT_CLASSES_KEY, - m_contextInfo.metaData.getString("android.app.static_init_classes").split(":")); - } - loaderParams.putStringArrayList(NATIVE_LIBRARIES_KEY, libraryList); - - - String themePath = m_context.getApplicationInfo().dataDir + "/qt-reserved-files/android-style/"; - String stylePath = themePath + m_displayDensity + "/"; - - String extractOption = "default"; - if (m_contextInfo.metaData.containsKey("android.app.extract_android_style")) { - extractOption = m_contextInfo.metaData.getString("android.app.extract_android_style"); - if (!extractOption.equals("default") && !extractOption.equals("full") && !extractOption.equals("minimal") && !extractOption.equals("none")) { - Log.e(QtApplication.QtTAG, "Invalid extract_android_style option \"" + extractOption + "\", defaulting to \"default\""); - extractOption = "default"; - } - } - - // QTBUG-69810: The extraction code will trigger compatibility warnings on Android SDK version >= 28 - // when the target SDK version is set to something lower then 28, so default to "none" and issue a warning - // if that is the case. - if (extractOption.equals("default")) { - final int targetSdkVersion = m_context.getApplicationInfo().targetSdkVersion; - if (targetSdkVersion < 28 && Build.VERSION.SDK_INT >= 28) { - Log.e(QtApplication.QtTAG, "extract_android_style option set to \"none\" when targetSdkVersion is less then 28"); - extractOption = "none"; - } - } - - if (!(new File(stylePath)).exists() && !extractOption.equals("none")) { - loaderParams.putString(EXTRACT_STYLE_KEY, stylePath); - loaderParams.putBoolean(EXTRACT_STYLE_MINIMAL_KEY, extractOption.equals("minimal")); - } - - if (extractOption.equals("full")) - ENVIRONMENT_VARIABLES += "\tQT_USE_ANDROID_NATIVE_STYLE=1"; - - ENVIRONMENT_VARIABLES += "\tMINISTRO_ANDROID_STYLE_PATH=" + stylePath - + "\tQT_ANDROID_THEMES_ROOT_PATH=" + themePath; - - loaderParams.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES); - - String appParams = null; - if (APPLICATION_PARAMETERS != null) - appParams = APPLICATION_PARAMETERS; - - Intent intent = getIntent(); - if (intent != null) { - String parameters = intent.getStringExtra("applicationArguments"); - if (parameters != null) - if (appParams == null) - appParams = parameters; - else - appParams += '\t' + parameters; - } - - if (m_contextInfo.metaData.containsKey("android.app.arguments")) { - String parameters = m_contextInfo.metaData.getString("android.app.arguments"); - if (appParams == null) - appParams = parameters; - else - appParams += '\t' + parameters; - } - - if (appParams != null) - loaderParams.putString(APPLICATION_PARAMETERS_KEY, appParams.replace(' ', '\t').trim()); - - loadApplication(loaderParams); - return; - } - - try { - if (!m_context.bindService(new Intent(org.kde.necessitas.ministro.IMinistro.class.getCanonicalName()), - m_ministroConnection, - Context.BIND_AUTO_CREATE)) { - throw new SecurityException(""); - } - } catch (Exception e) { - if (firstStart) { - String msg = "This application requires Ministro service. Would you like to install it?"; - if (m_contextInfo.metaData.containsKey("android.app.ministro_needed_msg")) - msg = m_contextInfo.metaData.getString("android.app.ministro_needed_msg"); - downloadUpgradeMinistro(msg); - } else { - ministroNotFound(); - } - } - } catch (Exception e) { - Log.e(QtApplication.QtTAG, "Can't create main activity", e); - } - } -} diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtService.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtService.java deleted file mode 100644 index cdd6c1efea..0000000000 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtService.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - Copyright (c) 2016, BogDan Vatra - Contact: http://www.qt.io/licensing/ - - Commercial License Usage - Licensees holding valid commercial Qt licenses may use this file in - accordance with the commercial license agreement provided with the - Software or, alternatively, in accordance with the terms contained in - a written agreement between you and The Qt Company. For licensing terms - and conditions see http://www.qt.io/terms-conditions. For further - information use the contact form at http://www.qt.io/contact-us. - - BSD License Usage - Alternatively, this file may be used under the BSD license as follows: - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package org.qtproject.qt5.android.bindings; - -import android.app.Service; -import android.content.Intent; -import android.content.res.Configuration; -import android.os.IBinder; - -public class QtService extends Service -{ - QtServiceLoader m_loader = new QtServiceLoader(this); - - - /////////////////////////// forward all notifications //////////////////////////// - /////////////////////////// Super class calls //////////////////////////////////// - /////////////// PLEASE DO NOT CHANGE THE FOLLOWING CODE ////////////////////////// - ////////////////////////////////////////////////////////////////////////////////// - protected void onCreateHook() { - m_loader.onCreate(); - } - @Override - public void onCreate() - { - super.onCreate(); - onCreateHook(); - } - //--------------------------------------------------------------------------- - - @Override - public void onDestroy() - { - super.onDestroy(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - public IBinder onBind(Intent intent) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(intent); - if (res.invoked) - return (IBinder)res.methodReturns; - else - return null; - } - //--------------------------------------------------------------------------- - - @Override - public void onConfigurationChanged(Configuration newConfig) - { - if (!QtApplication.invokeDelegate(newConfig).invoked) - super.onConfigurationChanged(newConfig); - } - public void super_onConfigurationChanged(Configuration newConfig) - { - super.onConfigurationChanged(newConfig); - } - //--------------------------------------------------------------------------- - - @Override - public void onLowMemory() - { - if (!QtApplication.invokeDelegate().invoked) - super.onLowMemory(); - } - //--------------------------------------------------------------------------- - - @Override - public int onStartCommand(Intent intent, int flags, int startId) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(intent, flags, startId); - if (res.invoked) - return (Integer) res.methodReturns; - else - return super.onStartCommand(intent, flags, startId); - } - public int super_onStartCommand(Intent intent, int flags, int startId) - { - return super.onStartCommand(intent, flags, startId); - } - //--------------------------------------------------------------------------- - - @Override - public void onTaskRemoved(Intent rootIntent) - { - if (!QtApplication.invokeDelegate(rootIntent).invoked) - super.onTaskRemoved(rootIntent); - } - public void super_onTaskRemoved(Intent rootIntent) - { - super.onTaskRemoved(rootIntent); - } - //--------------------------------------------------------------------------- - - @Override - public void onTrimMemory(int level) - { - if (!QtApplication.invokeDelegate(level).invoked) - super.onTrimMemory(level); - } - public void super_onTrimMemory(int level) - { - super.onTrimMemory(level); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onUnbind(Intent intent) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(intent); - if (res.invoked) - return (Boolean) res.methodReturns; - else - return super.onUnbind(intent); - } - public boolean super_onUnbind(Intent intent) - { - return super.onUnbind(intent); - } - //--------------------------------------------------------------------------- -} diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtServiceLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtServiceLoader.java deleted file mode 100644 index e32a4048e1..0000000000 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtServiceLoader.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (c) 2016, BogDan Vatra - Contact: http://www.qt.io/licensing/ - - Commercial License Usage - Licensees holding valid commercial Qt licenses may use this file in - accordance with the commercial license agreement provided with the - Software or, alternatively, in accordance with the terms contained in - a written agreement between you and The Qt Company. For licensing terms - and conditions see http://www.qt.io/terms-conditions. For further - information use the contact form at http://www.qt.io/contact-us. - - BSD License Usage - Alternatively, this file may be used under the BSD license as follows: - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package org.qtproject.qt5.android.bindings; - -import android.os.Bundle; -import android.content.ComponentName; -import android.content.pm.PackageManager; - -public class QtServiceLoader extends QtLoader { - QtService m_service; - QtServiceLoader(QtService service) { - super(service, QtService.class); - m_service = service; - } - - public void onCreate() { - try { - m_contextInfo = m_service.getPackageManager().getServiceInfo(new ComponentName(m_service, m_service.getClass()), PackageManager.GET_META_DATA); - } catch (Exception e) { - e.printStackTrace(); - m_service.stopSelf(); - return; - } - - if (QtApplication.m_delegateObject != null && QtApplication.onCreate != null) { - Bundle bundle = null; - QtApplication.invokeDelegateMethod(QtApplication.onCreate, bundle); - } - startApp(true); - } - - @Override - protected void finish() { - m_service.stopSelf(); - } - - @Override - protected String loaderClassName() { - return "org.qtproject.qt5.android.QtServiceDelegate"; - } - - @Override - protected Class contextClassName() { - return android.app.Service.class; - } -} -- cgit v1.2.3