summaryrefslogtreecommitdiffstats
path: root/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java')
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java325
1 files changed, 325 insertions, 0 deletions
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java
new file mode 100644
index 0000000000..3cb6ba220e
--- /dev/null
+++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java
@@ -0,0 +1,325 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+package org.qtproject.qt.android;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.provider.Browser;
+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.Window;
+
+public class QtActivityBase extends Activity
+{
+ private String m_applicationParams = "";
+ private boolean m_isCustomThemeSet = false;
+ private boolean m_retainNonConfigurationInstance = false;
+
+ private QtActivityDelegate m_delegate;
+
+ public static final String EXTRA_SOURCE_INFO = "org.qtproject.qt.android.sourceInfo";
+
+ private void addReferrer(Intent intent)
+ {
+ if (intent.getExtras() != null && intent.getExtras().getString(EXTRA_SOURCE_INFO) != null)
+ return;
+
+ String browserApplicationId = "";
+ if (intent.getExtras() != null)
+ browserApplicationId = intent.getExtras().getString(Browser.EXTRA_APPLICATION_ID);
+
+ String sourceInformation = "";
+ if (browserApplicationId != null && !browserApplicationId.isEmpty()) {
+ sourceInformation = browserApplicationId;
+ } else {
+ Uri referrer = getReferrer();
+ if (referrer != null)
+ sourceInformation = referrer.toString().replaceFirst("android-app://", "");
+ }
+
+ intent.putExtra(EXTRA_SOURCE_INFO, sourceInformation);
+ }
+
+ // Append any parameters to your application.
+ // Either a whitespace or a tab is accepted as a separator between parameters.
+ /** @noinspection unused*/
+ public void appendApplicationParameters(String params)
+ {
+ if (params == null || params.isEmpty())
+ return;
+
+ if (!m_applicationParams.isEmpty())
+ m_applicationParams += " ";
+ m_applicationParams += params;
+ }
+
+ private void handleActivityRestart() {
+ if (QtNative.getStateDetails().isStarted) {
+ boolean updated = m_delegate.updateActivityAfterRestart(this);
+ if (!updated) {
+ // could not update the activity so restart the application
+ Intent intent = Intent.makeRestartActivityTask(getComponentName());
+ startActivity(intent);
+ QtNative.quitApp();
+ Runtime.getRuntime().exit(0);
+ }
+ }
+ }
+
+ @Override
+ public void setTheme(int resId) {
+ super.setTheme(resId);
+ m_isCustomThemeSet = true;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_ACTION_BAR);
+
+ if (!m_isCustomThemeSet) {
+ setTheme(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ?
+ android.R.style.Theme_DeviceDefault_DayNight :
+ android.R.style.Theme_Holo_Light);
+ }
+
+ m_delegate = new QtActivityDelegate(this);
+
+ handleActivityRestart();
+ addReferrer(getIntent());
+
+ QtActivityLoader loader = new QtActivityLoader(this);
+ loader.appendApplicationParameters(m_applicationParams);
+
+ loader.loadQtLibraries();
+ m_delegate.startNativeApplication(loader.getApplicationParameters(),
+ loader.getMainLibraryPath());
+ }
+
+ @Override
+ protected void onStart()
+ {
+ super.onStart();
+ }
+
+ @Override
+ protected void onRestart()
+ {
+ super.onRestart();
+ }
+
+ @Override
+ protected void onPause()
+ {
+ super.onPause();
+ if (Build.VERSION.SDK_INT < 24 || !isInMultiWindowMode())
+ QtNative.setApplicationState(QtNative.ApplicationState.ApplicationInactive);
+ m_delegate.displayManager().unregisterDisplayListener();
+ }
+
+ @Override
+ protected void onResume()
+ {
+ super.onResume();
+ QtNative.setApplicationState(QtNative.ApplicationState.ApplicationActive);
+ if (QtNative.getStateDetails().isStarted) {
+ m_delegate.displayManager().registerDisplayListener();
+ QtNative.updateWindow();
+ // Suspending the app clears the immersive mode, so we need to set it again.
+ m_delegate.displayManager().updateFullScreen();
+ }
+ }
+
+ @Override
+ protected void onStop()
+ {
+ super.onStop();
+ QtNative.setApplicationState(QtNative.ApplicationState.ApplicationSuspended);
+ }
+
+ @Override
+ protected void onDestroy()
+ {
+ super.onDestroy();
+ if (!m_retainNonConfigurationInstance) {
+ QtNative.terminateQt();
+ QtNative.setActivity(null);
+ QtNative.getQtThread().exit();
+ System.exit(0);
+ }
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig)
+ {
+ super.onConfigurationChanged(newConfig);
+ m_delegate.handleUiModeChange(newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK);
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item)
+ {
+ m_delegate.setContextMenuVisible(false);
+ return QtNative.onContextItemSelected(item.getItemId(), item.isChecked());
+ }
+
+ @Override
+ public void onContextMenuClosed(Menu menu)
+ {
+ if (!m_delegate.isContextMenuVisible())
+ return;
+ m_delegate.setContextMenuVisible(false);
+ QtNative.onContextMenuClosed(menu);
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
+ {
+ menu.clearHeader();
+ QtNative.onCreateContextMenu(menu);
+ m_delegate.setContextMenuVisible(true);
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event)
+ {
+ boolean handleResult = m_delegate.getInputDelegate().handleDispatchKeyEvent(event);
+ if (QtNative.getStateDetails().isStarted && handleResult)
+ return true;
+
+ return super.dispatchKeyEvent(event);
+ }
+
+ @Override
+ public boolean dispatchGenericMotionEvent(MotionEvent event)
+ {
+ boolean handled = m_delegate.getInputDelegate().handleDispatchGenericMotionEvent(event);
+ if (QtNative.getStateDetails().isStarted && handled)
+ return true;
+
+ return super.dispatchGenericMotionEvent(event);
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event)
+ {
+ QtNative.ApplicationStateDetails stateDetails = QtNative.getStateDetails();
+ if (!stateDetails.isStarted || !stateDetails.nativePluginIntegrationReady)
+ return false;
+
+ return m_delegate.getInputDelegate().onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event)
+ {
+ QtNative.ApplicationStateDetails stateDetails = QtNative.getStateDetails();
+ if (!stateDetails.isStarted || !stateDetails.nativePluginIntegrationReady)
+ return false;
+
+ return m_delegate.getInputDelegate().onKeyUp(keyCode, event);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ menu.clear();
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu)
+ {
+ boolean res = QtNative.onPrepareOptionsMenu(menu);
+ m_delegate.setActionBarVisibility(res && menu.size() > 0);
+ return res;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ return QtNative.onOptionsItemSelected(item.getItemId(), item.isChecked());
+ }
+
+ @Override
+ public void onOptionsMenuClosed(Menu menu)
+ {
+ QtNative.onOptionsMenuClosed(menu);
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState)
+ {
+ super.onRestoreInstanceState(savedInstanceState);
+ QtNative.setStarted(savedInstanceState.getBoolean("Started"));
+ int savedSystemUiVisibility = savedInstanceState.getInt("SystemUiVisibility");
+ m_delegate.displayManager().setSystemUiVisibility(savedSystemUiVisibility);
+ // FIXME restore all surfaces
+ }
+
+ @Override
+ public Object onRetainNonConfigurationInstance()
+ {
+ super.onRetainNonConfigurationInstance();
+ m_retainNonConfigurationInstance = true;
+ return true;
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState)
+ {
+ super.onSaveInstanceState(outState);
+ outState.putInt("SystemUiVisibility", m_delegate.displayManager().systemUiVisibility());
+ outState.putBoolean("Started", QtNative.getStateDetails().isStarted);
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus)
+ {
+ super.onWindowFocusChanged(hasFocus);
+ if (hasFocus)
+ m_delegate.displayManager().updateFullScreen();
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent)
+ {
+ QtNative.onNewIntent(intent);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data)
+ {
+ super.onActivityResult(requestCode, resultCode, data);
+ QtNative.onActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
+ {
+ QtNative.sendRequestPermissionsResult(requestCode, permissions, grantResults);
+ }
+
+ @UsedFromNativeCode
+ public void hideSplashScreen(final int duration)
+ {
+ m_delegate.hideSplashScreen(duration);
+ }
+
+ @UsedFromNativeCode
+ QtActivityDelegateBase getActivityDelegate()
+ {
+ return m_delegate;
+ }
+}