diff --git a/dependencies.gradle b/dependencies.gradle
index a0ac311963f..0fd445b543b 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -1,13 +1,13 @@
ext.versions = [
'minSdk' : 21,
- 'compileSdk' : 34,
- 'targetSdk' : 34,
+ 'compileSdk' : 35,
+ 'targetSdk' : 35,
'sourceCompat' : JavaVersion.VERSION_21,
'targetCompat' : JavaVersion.VERSION_21,
'jvmTarget' : "21",
]
-def gradle = "8.4.2"
+def gradle = "8.11.0"
// Ref: https://kotlinlang.org/releases.html
def kotlin = "1.9.24"
def kotlinCoroutines = "1.8.1"
diff --git a/gradle.properties b/gradle.properties
index 8cde2fc6875..2433ae78cbd 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -42,4 +42,4 @@ signing.element.nightly.keyPassword=Secret
# Customise the Lint version to use a more recent version than the one bundled with AGP
# https://googlesamples.github.io/android-custom-lint-rules/usage/newer-lint.md.html
-android.experimental.lint.version=8.6.0-alpha08
+android.experimental.lint.version=8.12.0-alpha08
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index e6441136f3d..1b33c55baab 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 515ab9d5f18..78cb6e16a49 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionSha256Sum=f8b4f4772d302c8ff580bc40d0f56e715de69b163546944f787c87abf209c961
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip
+distributionSha256Sum=bd71102213493060956ec229d946beee57158dbd89d0e62b91bca0fa2c5f3531
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
index 65dcd68d65c..23d15a93670 100755
--- a/gradlew
+++ b/gradlew
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+# SPDX-License-Identifier: Apache-2.0
+#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -83,10 +85,8 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@@ -133,10 +133,13 @@ location of your Java installation."
fi
else
JAVACMD=java
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
+ fi
fi
# Increase the maximum file descriptors if we can.
@@ -144,7 +147,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC3045
+ # shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@@ -152,7 +155,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC3045
+ # shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -197,16 +200,20 @@ if "$cygwin" || "$msys" ; then
done
fi
-# Collect all arguments for the java command;
-# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
-# shell script including quotes and variable substitutions, so put them in
-# double quotes to make sure that they get re-expanded; and
-# * put everything else in single quotes, so that it's not re-expanded.
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
- org.gradle.wrapper.GradleWrapperMain \
+ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
diff --git a/gradlew.bat b/gradlew.bat
index 6689b85beec..5eed7ee8452 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
@@ -57,22 +59,22 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+set CLASSPATH=
@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
diff --git a/library/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt b/library/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt
index 09785e50e79..55a3b5d511b 100644
--- a/library/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt
+++ b/library/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt
@@ -131,12 +131,15 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
// the touch coordinates
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ @Suppress("DEPRECATION")
window.setDecorFitsSystemWindows(false)
// New API instead of SYSTEM_UI_FLAG_IMMERSIVE
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
// New API instead of FLAG_TRANSLUCENT_STATUS
+ @Suppress("DEPRECATION")
window.statusBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
// new API instead of FLAG_TRANSLUCENT_NAVIGATION
+ @Suppress("DEPRECATION")
window.navigationBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
} else {
@Suppress("DEPRECATION")
@@ -318,6 +321,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
protected open fun shouldAnimateDismiss(): Boolean = true
protected open fun animateClose() {
+ @Suppress("DEPRECATION")
window.statusBarColor = Color.TRANSPARENT
finish()
}
@@ -334,14 +338,17 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
// Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ @Suppress("DEPRECATION")
window.setDecorFitsSystemWindows(false)
// new API instead of SYSTEM_UI_FLAG_HIDE_NAVIGATION
window.decorView.windowInsetsController?.hide(WindowInsets.Type.navigationBars())
// New API instead of SYSTEM_UI_FLAG_IMMERSIVE
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
// New API instead of FLAG_TRANSLUCENT_STATUS
+ @Suppress("DEPRECATION")
window.statusBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
// New API instead of FLAG_TRANSLUCENT_NAVIGATION
+ @Suppress("DEPRECATION")
window.navigationBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
} else {
@Suppress("DEPRECATION")
@@ -363,6 +370,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
systemUiVisibility = true
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ @Suppress("DEPRECATION")
window.setDecorFitsSystemWindows(false)
} else {
@Suppress("DEPRECATION")
diff --git a/library/ui-styles/src/main/res/values/theme_light.xml b/library/ui-styles/src/main/res/values/theme_light.xml
index bd397d1bc68..68a0e8a5feb 100644
--- a/library/ui-styles/src/main/res/values/theme_light.xml
+++ b/library/ui-styles/src/main/res/values/theme_light.xml
@@ -64,6 +64,9 @@
- @color/element_accent_light
+
+
+ - ?vctr_toolbar_background
- @color/element_accent_light
- @android:color/white
- @color/element_accent_light
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt
index 334a8c50766..f11b8a031c9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt
@@ -38,7 +38,8 @@ internal class FormattedJsonHttpLogger(
*/
@Synchronized
override fun log(message: String) {
- Timber.v(message)
+ Timber.v(message.take(20_000))
+ if (message.length > 20_000) return
// Try to log formatted Json only if there is a chance that [message] contains Json.
// It can be only the case if we log the bodies of Http requests.
diff --git a/vector-app/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt
index 288b7a89bd8..876baf69d95 100644
--- a/vector-app/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt
@@ -12,6 +12,7 @@ import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Intent
import android.os.Build
+import android.view.View
import androidx.core.app.NotificationCompat
import androidx.core.app.Person
import androidx.core.content.getSystemService
@@ -49,7 +50,9 @@ import javax.inject.Inject
class DebugMenuActivity : VectorBaseActivity() {
override fun getBinding() = ActivityDebugMenuBinding.inflate(layoutInflater)
-
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
@Inject lateinit var clock: Clock
private lateinit var buffer: ByteArray
diff --git a/vector-app/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt
index cae9f63b225..9f5622713ba 100644
--- a/vector-app/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.debug
import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
+import android.view.View
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
@@ -32,6 +33,9 @@ class DebugPermissionActivity : VectorBaseActivity() {
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
if (isFirstCreation()) {
addFragment(
diff --git a/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesSettingsActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesSettingsActivity.kt
index 2f7ff692af0..b4a77939629 100644
--- a/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesSettingsActivity.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesSettingsActivity.kt
@@ -8,6 +8,7 @@
package im.vector.app.features.debug.features
import android.os.Bundle
+import android.view.View
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
@@ -24,6 +25,9 @@ class DebugFeaturesSettingsActivity : VectorBaseActivity() {
override fun getBinding() = ActivityDebugJitsiBinding.inflate(layoutInflater)
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
@SuppressLint("SetTextI18n")
override fun initUiAndData() {
diff --git a/vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt
index f942fc342d4..7eb9ea99d62 100644
--- a/vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt
@@ -7,6 +7,7 @@
package im.vector.app.features.debug.leak
+import android.view.View
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.VectorBaseActivity
@@ -17,6 +18,10 @@ class DebugMemoryLeaksActivity : VectorBaseActivity() {
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
if (isFirstCreation()) {
addFragment(
diff --git a/vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsActivity.kt
index 017bde5eb79..2a539a21ca4 100644
--- a/vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsActivity.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsActivity.kt
@@ -7,6 +7,7 @@
package im.vector.app.features.debug.settings
+import android.view.View
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.VectorBaseActivity
@@ -17,6 +18,10 @@ class DebugPrivateSettingsActivity : VectorBaseActivity()
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
if (isFirstCreation()) {
addFragment(
diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml
index fab5be1257d..7455c0847f4 100644
--- a/vector/src/main/AndroidManifest.xml
+++ b/vector/src/main/AndroidManifest.xml
@@ -167,8 +167,7 @@
+ android:parentActivityName=".features.home.HomeActivity">
@@ -369,8 +368,8 @@
+ android:exported="false"
+ android:foregroundServiceType="phoneCall">
@@ -387,7 +386,8 @@
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
+ tools:targetApi="M">
@@ -413,8 +413,7 @@
android:name=".features.call.audio.MicrophoneAccessService"
android:exported="false"
android:foregroundServiceType="microphone"
- android:permission="android.permission.FOREGROUND_SERVICE_MICROPHONE">
-
+ android:permission="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
diff --git a/vector/src/main/java/im/vector/app/SpaceStateHandlerImpl.kt b/vector/src/main/java/im/vector/app/SpaceStateHandlerImpl.kt
index 97b6eb6209b..06abc16cbfe 100644
--- a/vector/src/main/java/im/vector/app/SpaceStateHandlerImpl.kt
+++ b/vector/src/main/java/im/vector/app/SpaceStateHandlerImpl.kt
@@ -137,7 +137,7 @@ class SpaceStateHandlerImpl @Inject constructor(
override fun popSpaceBackstack(): String? {
vectorPreferences.getSpaceBackstack().toMutableList().apply {
- val poppedSpaceId = removeLast()
+ val poppedSpaceId = removeAt(lastIndex)
vectorPreferences.setSpaceBackstack(this)
return poppedSpaceId
}
diff --git a/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt b/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt
index 06eecf1d41e..12ed8418bc3 100644
--- a/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt
+++ b/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt
@@ -6,6 +6,7 @@
*/
package im.vector.app.core.platform
+import android.view.View
import androidx.core.view.isGone
import androidx.core.view.isVisible
import im.vector.app.core.extensions.hideKeyboard
@@ -20,6 +21,9 @@ abstract class SimpleFragmentActivity : VectorBaseActivity() {
final override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
setupToolbar(views.toolbar)
.allowBack(true)
diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt
index 355a164ab07..a6b9d779307 100644
--- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt
+++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt
@@ -10,25 +10,26 @@ package im.vector.app.core.platform
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
-import android.os.Build
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
-import android.view.WindowInsetsController
import android.view.WindowManager
import android.widget.TextView
+import androidx.activity.enableEdgeToEdge
import androidx.annotation.CallSuper
import androidx.annotation.MainThread
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.app.MultiWindowModeChangedInfo
-import androidx.core.content.ContextCompat
import androidx.core.util.Consumer
import androidx.core.view.MenuProvider
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
+import androidx.core.view.updatePadding
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
@@ -208,6 +209,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver
val activityEntryPoint = EntryPointAccessors.fromActivity(this, ActivityEntryPoint::class.java)
ThemeUtils.setActivityTheme(this, getOtherThemes())
viewModelFactory = activityEntryPoint.viewModelFactory()
+ enableEdgeToEdge()
super.onCreate(savedInstanceState)
addOnMultiWindowModeChangedListener(onMultiWindowModeChangedListener)
setupMenu()
@@ -247,7 +249,9 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver
if (vectorPreferences.isNewAppLayoutEnabled()) {
tryOrNull { // Add to XML theme when feature flag is removed
val toolbarBackground = MaterialColors.getColor(views.root, im.vector.lib.ui.styles.R.attr.vctr_toolbar_background)
+ @Suppress("DEPRECATION")
window.statusBarColor = toolbarBackground
+ @Suppress("DEPRECATION")
window.navigationBarColor = toolbarBackground
}
}
@@ -334,7 +338,8 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver
private fun handleCertificateError(certificateError: GlobalError.CertificateError) {
singletonEntryPoint()
.unrecognizedCertificateDialog()
- .show(this,
+ .show(
+ this,
certificateError.fingerprint,
object : UnrecognizedCertificateDialog.Callback {
override fun onAccept() {
@@ -411,6 +416,20 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver
// Just log that a change occurred.
Timber.w("MDM data has been updated")
}
+ ViewCompat.setOnApplyWindowInsetsListener(rootView) { v, insets ->
+ val systemBars = insets.getInsets(
+ WindowInsetsCompat.Type.systemBars() or
+ WindowInsetsCompat.Type.displayCutout() or
+ WindowInsetsCompat.Type.ime()
+ )
+ v.updatePadding(
+ systemBars.left,
+ systemBars.top,
+ systemBars.right,
+ systemBars.bottom,
+ )
+ insets
+ }
}
private val postResumeScheduledActions = mutableListOf<() -> Unit>()
@@ -444,14 +463,6 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver
mdmService.unregisterListener(this)
}
- override fun onWindowFocusChanged(hasFocus: Boolean) {
- super.onWindowFocusChanged(hasFocus)
-
- if (hasFocus && displayInFullscreen()) {
- setFullScreen()
- }
- }
-
private val onMultiWindowModeChangedListener = Consumer {
Timber.w("onMultiWindowModeChanged. isInMultiWindowMode: ${it.isInMultiWindowMode}")
bugReporter.inMultiWindowMode = it.isInMultiWindowMode
@@ -461,30 +472,6 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver
* PRIVATE METHODS
* ========================================================================================== */
- /**
- * Force to render the activity in fullscreen.
- */
- private fun setFullScreen() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
- // New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- window.setDecorFitsSystemWindows(false)
- // New API instead of SYSTEM_UI_FLAG_IMMERSIVE
- window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
- // New API instead of FLAG_TRANSLUCENT_STATUS
- window.statusBarColor = ContextCompat.getColor(this, im.vector.lib.ui.styles.R.color.half_transparent_status_bar)
- // New API instead of FLAG_TRANSLUCENT_NAVIGATION
- window.navigationBarColor = ContextCompat.getColor(this, im.vector.lib.ui.styles.R.color.half_transparent_status_bar)
- } else {
- @Suppress("DEPRECATION")
- window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
- or View.SYSTEM_UI_FLAG_FULLSCREEN
- or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
- }
- }
-
private fun handleMenuItemHome(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
@@ -586,8 +573,6 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver
abstract fun getBinding(): VB
- open fun displayInFullscreen() = false
-
open fun doBeforeSetContentView() = Unit
open fun initUiAndData() = Unit
@@ -626,6 +611,8 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver
open fun getCoordinatorLayout(): CoordinatorLayout? = null
+ abstract val rootView: View
+
/* ==========================================================================================
* User Consent
* ========================================================================================== */
diff --git a/vector/src/main/java/im/vector/app/core/services/BluetoothHeadsetReceiver.kt b/vector/src/main/java/im/vector/app/core/services/BluetoothHeadsetReceiver.kt
index dd04e5664e5..031ea2268de 100644
--- a/vector/src/main/java/im/vector/app/core/services/BluetoothHeadsetReceiver.kt
+++ b/vector/src/main/java/im/vector/app/core/services/BluetoothHeadsetReceiver.kt
@@ -18,6 +18,10 @@ import androidx.core.content.ContextCompat
import im.vector.lib.core.utils.compat.getParcelableExtraCompat
import java.lang.ref.WeakReference
+/**
+ * It's only used in API 21 and 22 so we will not have security exception on these OS,
+ * so it's safe to use @Suppress("MissingPermission").
+ */
class BluetoothHeadsetReceiver : BroadcastReceiver() {
interface EventListener {
@@ -53,12 +57,15 @@ class BluetoothHeadsetReceiver : BroadcastReceiver() {
}
val device = intent.getParcelableExtraCompat(BluetoothDevice.EXTRA_DEVICE)
+ @Suppress("MissingPermission")
val deviceName = device?.name
+ @Suppress("MissingPermission")
when (device?.bluetoothClass?.deviceClass) {
BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE,
BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO,
BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET -> {
// filter only device that we care about for
+ @Suppress("MissingPermission")
delegate?.get()?.onBTHeadsetEvent(
BTHeadsetPlugEvent(
plugged = headsetConnected,
diff --git a/vector/src/main/java/im/vector/app/core/services/CallAndroidService.kt b/vector/src/main/java/im/vector/app/core/services/CallAndroidService.kt
index f818ab412eb..9e0a718b156 100644
--- a/vector/src/main/java/im/vector/app/core/services/CallAndroidService.kt
+++ b/vector/src/main/java/im/vector/app/core/services/CallAndroidService.kt
@@ -8,11 +8,14 @@
package im.vector.app.core.services
+import android.Manifest
import android.content.Context
import android.content.Intent
+import android.content.pm.PackageManager
import android.os.Binder
import android.support.v4.media.session.MediaSessionCompat
import android.view.KeyEvent
+import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import androidx.media.session.MediaButtonReceiver
@@ -150,7 +153,8 @@ class CallAndroidService : VectorAndroidService() {
val isVideoCall = call.mxCall.isVideoCall
val fromBg = intent.getBooleanExtra(EXTRA_IS_IN_BG, false)
Timber.tag(loggerTag.value).v("displayIncomingCallNotification : display the dedicated notification")
- val incomingCallAlert = IncomingCallAlert(callId,
+ val incomingCallAlert = IncomingCallAlert(
+ callId,
shouldBeDisplayedIn = { activity ->
if (activity is VectorCallActivity) {
activity.intent.getParcelableExtraCompat(Mavericks.KEY_ARG)?.callId != call.callId
@@ -176,7 +180,11 @@ class CallAndroidService : VectorAndroidService() {
if (knownCalls.isEmpty()) {
startForegroundCompat(callId.hashCode(), notification)
} else {
- notificationManager.notify(callId.hashCode(), notification)
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
+ Timber.w("Not allowed to notify.")
+ } else {
+ notificationManager.notify(callId.hashCode(), notification)
+ }
}
knownCalls[callId] = callInformation
}
@@ -234,7 +242,11 @@ class CallAndroidService : VectorAndroidService() {
if (knownCalls.isEmpty()) {
startForegroundCompat(callId.hashCode(), notification)
} else {
- notificationManager.notify(callId.hashCode(), notification)
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
+ Timber.w("Not allowed to notify.")
+ } else {
+ notificationManager.notify(callId.hashCode(), notification)
+ }
}
knownCalls[callId] = callInformation
}
@@ -258,7 +270,11 @@ class CallAndroidService : VectorAndroidService() {
if (knownCalls.isEmpty()) {
startForegroundCompat(callId.hashCode(), notification)
} else {
- notificationManager.notify(callId.hashCode(), notification)
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
+ Timber.w("Not allowed to notify.")
+ } else {
+ notificationManager.notify(callId.hashCode(), notification)
+ }
}
knownCalls[callId] = callInformation
}
diff --git a/vector/src/main/java/im/vector/app/core/utils/ExpandingBottomSheetBehavior.kt b/vector/src/main/java/im/vector/app/core/utils/ExpandingBottomSheetBehavior.kt
index 7834d6a0142..5b84579b2b1 100644
--- a/vector/src/main/java/im/vector/app/core/utils/ExpandingBottomSheetBehavior.kt
+++ b/vector/src/main/java/im/vector/app/core/utils/ExpandingBottomSheetBehavior.kt
@@ -658,7 +658,8 @@ class ExpandingBottomSheetBehavior : CoordinatorLayout.Behavior {
val insetsType = WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime()
val imeInsets = insets.getInsets(insetsType)
insetTop = imeInsets.top
- insetBottom = imeInsets.bottom
+ // Now that edgeToEdge is enabled, disable the bottom padding.
+ insetBottom = 0
insetLeft = imeInsets.left
insetRight = imeInsets.right
diff --git a/vector/src/main/java/im/vector/app/core/utils/PermissionChecker.kt b/vector/src/main/java/im/vector/app/core/utils/PermissionChecker.kt
new file mode 100644
index 00000000000..3840e028c0a
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/core/utils/PermissionChecker.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2025 New Vector Ltd.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
+ * Please see LICENSE files in the repository root for full details.
+ */
+
+package im.vector.app.core.utils
+
+import android.content.Context
+import android.content.pm.PackageManager
+import androidx.core.app.ActivityCompat
+import javax.inject.Inject
+
+class PermissionChecker @Inject constructor(
+ private val applicationContext: Context,
+) {
+ fun checkPermission(vararg permissions: String): Boolean {
+ return permissions.any { permission ->
+ ActivityCompat.checkSelfPermission(applicationContext, permission) != PackageManager.PERMISSION_GRANTED
+ }
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt
index 6b16c2deb80..9c95a5d835b 100644
--- a/vector/src/main/java/im/vector/app/features/MainActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt
@@ -12,6 +12,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Parcelable
+import android.view.View
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
@@ -392,4 +393,7 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity
val className = componentName.className
return packageName == buildMeta.applicationId && className in allowList
}
+
+ override val rootView: View
+ get() = views.mainRoot
}
diff --git a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInActivity.kt b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInActivity.kt
index e3cf06bd87f..42598f43561 100644
--- a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInActivity.kt
@@ -7,6 +7,7 @@
package im.vector.app.features.analytics.ui.consent
+import android.view.View
import com.airbnb.mvrx.viewModel
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
@@ -29,6 +30,9 @@ class AnalyticsOptInActivity : VectorBaseActivity() {
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
orientationLocker.lockPhonesToPortrait(this)
if (isFirstCreation()) {
diff --git a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt
index 487e116fb5d..5382d546705 100644
--- a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt
@@ -9,6 +9,7 @@ package im.vector.app.features.attachments.preview
import android.content.Context
import android.content.Intent
+import android.view.View
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.VectorBaseActivity
@@ -47,6 +48,9 @@ class AttachmentsPreviewActivity : VectorBaseActivity() {
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
if (isFirstCreation()) {
val fragmentArgs: AttachmentsPreviewArgs = intent?.extras?.getParcelableCompat(EXTRA_FRAGMENT_ARGS) ?: return
diff --git a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewFragment.kt b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewFragment.kt
index 999b76295d4..a4f1dafda18 100644
--- a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewFragment.kt
@@ -163,6 +163,7 @@ class AttachmentsPreviewFragment :
private fun applyInsets() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ @Suppress("DEPRECATION")
activity?.window?.setDecorFitsSystemWindows(false)
} else {
@Suppress("DEPRECATION")
diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt
index 47db3dccc7e..03a3aaf8c98 100644
--- a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt
@@ -128,7 +128,9 @@ class VectorCallActivity :
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+ @Suppress("DEPRECATION")
window.statusBarColor = Color.TRANSPARENT
+ @Suppress("DEPRECATION")
window.navigationBarColor = Color.BLACK
super.onCreate(savedInstanceState)
addOnPictureInPictureModeChangedListener(pictureInPictureModeChangedInfoConsumer)
@@ -185,6 +187,9 @@ class VectorCallActivity :
override fun getMenuRes() = R.menu.vector_call
+ override val rootView: View
+ get() = views.constraintLayout
+
override fun onUserLeaveHint() {
super.onUserLeaveHint()
enterPictureInPictureIfRequired()
diff --git a/vector/src/main/java/im/vector/app/features/call/audio/API21AudioDeviceDetector.kt b/vector/src/main/java/im/vector/app/features/call/audio/API21AudioDeviceDetector.kt
index 30d65073800..69adc08c637 100644
--- a/vector/src/main/java/im/vector/app/features/call/audio/API21AudioDeviceDetector.kt
+++ b/vector/src/main/java/im/vector/app/features/call/audio/API21AudioDeviceDetector.kt
@@ -43,6 +43,11 @@ internal class API21AudioDeviceDetector(
return HashSet().apply {
if (isBluetoothHeadsetOn()) {
connectedBlueToothHeadset?.connectedDevices?.forEach {
+ // Call requires permission which may be rejected by user: code should explicitly
+ // check to see if permission is available (with checkPermission) or explicitly
+ // handle a potential SecurityException
+ // But it should not happen on API 21/22.
+ @Suppress("MissingPermission")
add(CallAudioManager.Device.WirelessHeadset(it.name))
}
}
diff --git a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt
index 4a0ccf28e3e..a86b5e34c93 100644
--- a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt
@@ -15,6 +15,7 @@ import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
+import android.view.View
import android.widget.FrameLayout
import android.widget.Toast
import androidx.core.app.PictureInPictureModeChangedInfo
@@ -58,6 +59,9 @@ class VectorJitsiActivity : VectorBaseActivity(), JitsiMee
override fun getBinding() = ActivityJitsiBinding.inflate(layoutInflater)
+ override val rootView: View
+ get() = views.jitsiLayout
+
private var jitsiMeetView: JitsiMeetView? = null
private val jitsiViewModel: JitsiCallViewModel by viewModel()
diff --git a/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt b/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt
index 7efe7b8df9d..5bb1b5d0dd1 100644
--- a/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt
@@ -12,7 +12,6 @@ import android.content.ClipboardManager
import android.content.Context
import android.content.res.ColorStateList
import android.os.Bundle
-import android.telephony.PhoneNumberFormattingTextWatcher
import android.telephony.PhoneNumberUtils
import android.text.Editable
import android.text.InputType
@@ -78,7 +77,8 @@ class DialPadFragment : Fragment(), TextWatcher {
digits.inputType = InputType.TYPE_CLASS_PHONE
digits.keyListener = DialerKeyListener.getInstance()
digits.setTextColor(ThemeUtils.getColor(requireContext(), im.vector.lib.ui.styles.R.attr.vctr_content_primary))
- digits.addTextChangedListener(PhoneNumberFormattingTextWatcher(if (formatAsYouType) regionCode else ""))
+ @Suppress("DEPRECATION")
+ digits.addTextChangedListener(android.telephony.PhoneNumberFormattingTextWatcher(if (formatAsYouType) regionCode else ""))
digits.addTextChangedListener(this)
dialpadView.findViewById(R.id.zero).setOnClickListener { keyPressed(KeyEvent.KEYCODE_0, "0") }
dialpadView.findViewById(R.id.one).setOnClickListener { keyPressed(KeyEvent.KEYCODE_1, "1") }
diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt
index 6a647bd5018..1925ce854e6 100644
--- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt
@@ -11,6 +11,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Parcelable
+import android.view.View
import com.airbnb.mvrx.Mavericks
import com.airbnb.mvrx.viewModel
import com.google.android.material.tabs.TabLayoutMediator
@@ -37,6 +38,9 @@ class CallTransferActivity : VectorBaseActivity() {
override fun getCoordinatorLayout() = views.vectorCoordinatorLayout
+ override val rootView: View
+ get() = views.vectorCoordinatorLayout
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
waitingView = views.waitingView.waitingView
diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt
index b1072576bc7..8a29bdd9e8e 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt
@@ -122,6 +122,7 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment= Build.VERSION_CODES.R) {
+ @Suppress("DEPRECATION")
dialog?.window?.setDecorFitsSystemWindows(false)
} else {
@Suppress("DEPRECATION")
diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt
index d22ea908564..bea9d1303ba 100644
--- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt
@@ -192,6 +192,9 @@ class HomeActivity :
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun getBinding() = ActivityHomeBinding.inflate(layoutInflater)
override fun onCreate(savedInstanceState: Bundle?) {
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt
index e65e6c17f08..e5d785af639 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt
@@ -14,7 +14,6 @@ import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.core.view.GravityCompat
-import androidx.core.view.WindowCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
@@ -82,6 +81,9 @@ class RoomDetailActivity :
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
@Inject lateinit var playbackTracker: AudioMessagePlaybackTracker
private lateinit var sharedActionViewModel: RoomDetailSharedActionViewModel
private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel()
@@ -93,7 +95,7 @@ class RoomDetailActivity :
super.onCreate(savedInstanceState)
// For dealing with insets and status bar background color
- WindowCompat.setDecorFitsSystemWindows(window, false)
+ @Suppress("DEPRECATION")
window.statusBarColor = Color.TRANSPARENT
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
index 8e7b9ca951c..01be29d84ff 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
@@ -32,11 +32,9 @@ import androidx.core.net.toUri
import androidx.core.text.toSpannable
import androidx.core.util.Pair
import androidx.core.view.ViewCompat
-import androidx.core.view.WindowInsetsCompat
import androidx.core.view.forEach
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
-import androidx.core.view.updatePadding
import androidx.fragment.app.setFragmentResultListener
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.withResumed
@@ -409,13 +407,6 @@ class TimelineFragment :
is RoomDetailViewEvents.RevokeFilePermission -> revokeFilePermission(it)
}
}
-
- ViewCompat.setOnApplyWindowInsetsListener(views.coordinatorLayout) { _, insets ->
- val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime() or WindowInsetsCompat.Type.systemBars())
- views.appBarLayout.updatePadding(top = imeInsets.top)
- views.voiceMessageRecorderContainer.updatePadding(bottom = imeInsets.bottom)
- insets
- }
}
private fun setupBackPressHandling() {
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt
index 0d674174c82..f262f5b044b 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.home.room.detail.search
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import androidx.appcompat.widget.SearchView
import com.airbnb.mvrx.Mavericks
import dagger.hilt.android.AndroidEntryPoint
@@ -30,6 +31,9 @@ class SearchActivity : VectorBaseActivity() {
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setupToolbar(views.searchToolbar)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt
index b2402ee4390..7e10e697974 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.home.room.filtered
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import androidx.appcompat.widget.SearchView
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.replaceFragment
@@ -32,6 +33,9 @@ class FilteredRoomsActivity : VectorBaseActivity()
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
analyticsScreenName = MobileScreen.ScreenName.RoomFilter
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/invites/InvitesActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/invites/InvitesActivity.kt
index f2a19545fe2..8976e580c5a 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/home/invites/InvitesActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/invites/InvitesActivity.kt
@@ -7,6 +7,7 @@
package im.vector.app.features.home.room.list.home.invites
+import android.view.View
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.VectorBaseActivity
@@ -22,4 +23,8 @@ class InvitesActivity : VectorBaseActivity() {
addFragment(views.simpleFragmentContainer, InvitesFragment::class.java)
}
}
+
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesActivity.kt
index 0a3fa4393af..e7c104ff050 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesActivity.kt
@@ -7,6 +7,7 @@
package im.vector.app.features.home.room.list.home.release
+import android.view.View
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
@@ -26,6 +27,9 @@ class ReleaseNotesActivity : VectorBaseActivity() {
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
orientationLocker.lockPhonesToPortrait(this)
if (isFirstCreation()) {
diff --git a/vector/src/main/java/im/vector/app/features/home/room/threads/ThreadsActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/threads/ThreadsActivity.kt
index e0b773c2b6c..9174f60e5b9 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/threads/ThreadsActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/threads/ThreadsActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.home.room.threads
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import androidx.fragment.app.FragmentTransaction
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragmentToBackstack
@@ -42,6 +43,9 @@ class ThreadsActivity : VectorBaseActivity() {
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initFragment()
diff --git a/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt b/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt
index fcb0dc22a81..968c422f433 100644
--- a/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt
+++ b/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt
@@ -32,7 +32,7 @@ class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager
/**
* The activities information collected from the app manifest.
*/
- private var activitiesInfo: Array = emptyArray()
+ private var activitiesInfo: List? = null
private val coroutineScope = CoroutineScope(SupervisorJob())
@@ -51,24 +51,32 @@ class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager
override fun onActivityStopped(activity: Activity) {}
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
- if (activitiesInfo.isEmpty()) {
+ if (activitiesInfo == null) {
val context = activity.applicationContext
val packageManager: PackageManager = context.packageManager
// Get all activities from element android
- activitiesInfo = packageManager.getPackageInfoCompat(context.packageName, PackageManager.GET_ACTIVITIES).activities
-
+ val activities = packageManager
+ .getPackageInfoCompat(context.packageName, PackageManager.GET_ACTIVITIES)
+ .activities
+ .orEmpty()
+ .toList()
// Get all activities from PermissionController module
// See https://source.android.com/docs/core/architecture/modular-system/permissioncontroller#package-format
- if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) {
- activitiesInfo += tryOrNull {
+ val otherActivities = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) {
+ (tryOrNull {
packageManager.getPackageInfoCompat("com.google.android.permissioncontroller", PackageManager.GET_ACTIVITIES).activities
} ?: tryOrNull {
packageManager.getModuleInfo("com.google.android.permission", 1).packageName?.let {
packageManager.getPackageInfoCompat(it, PackageManager.GET_ACTIVITIES or PackageManager.MATCH_APEX).activities
}
- }.orEmpty()
+ })
+ .orEmpty()
+ .toList()
+ } else {
+ emptyList()
}
+ activitiesInfo = activities + otherActivities
}
// restart the app if the task contains an unknown activity
@@ -144,5 +152,5 @@ class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager
* @param activity the activity of the task
* @return true if the activity is potentially malicious
*/
- private fun isPotentialMaliciousActivity(activity: ComponentName): Boolean = activitiesInfo.none { it.name == activity.className }
+ private fun isPotentialMaliciousActivity(activity: ComponentName): Boolean = activitiesInfo.orEmpty().none { it.name == activity.className }
}
diff --git a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt
index 5c3ba3fbc36..f8c90575710 100644
--- a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.link
import android.content.Intent
import android.net.Uri
import android.os.Bundle
+import android.view.View
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.viewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@@ -41,6 +42,9 @@ class LinkHandlerActivity : VectorBaseActivity() {
override fun getBinding() = ActivityProgressBinding.inflate(layoutInflater)
+ override val rootView: View
+ get() = views.mainRoot
+
override fun initUiAndData() {
handleIntent()
}
diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingActivity.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingActivity.kt
index d9d3ee0731b..70ef34d03b1 100644
--- a/vector/src/main/java/im/vector/app/features/location/LocationSharingActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.location
import android.content.Context
import android.content.Intent
import android.os.Parcelable
+import android.view.View
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.VectorBaseActivity
@@ -31,6 +32,9 @@ class LocationSharingActivity : VectorBaseActivity(initialState), LocationTracker.Callback {
private val room = session.getRoom(initialState.roomId)!!
@@ -88,7 +91,15 @@ class LocationSharingViewModel @AssistedInject constructor(
locationTracker.locations
.onEach(::onLocationUpdate)
.launchIn(viewModelScope)
- locationTracker.start()
+ if (permissionChecker.checkPermission(
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION,
+ )
+ ) {
+ locationTracker.start()
+ } else {
+ Timber.w("Not allowed to use location api.")
+ }
}
private fun setUserItem() {
diff --git a/vector/src/main/java/im/vector/app/features/location/LocationTracker.kt b/vector/src/main/java/im/vector/app/features/location/LocationTracker.kt
index 70e909de27c..1baebec6175 100644
--- a/vector/src/main/java/im/vector/app/features/location/LocationTracker.kt
+++ b/vector/src/main/java/im/vector/app/features/location/LocationTracker.kt
@@ -17,6 +17,7 @@ import androidx.core.content.getSystemService
import androidx.core.location.LocationListenerCompat
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.resources.BuildMeta
+import im.vector.app.core.utils.PermissionChecker
import im.vector.app.features.session.coroutineScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
@@ -37,6 +38,7 @@ class LocationTracker @Inject constructor(
context: Context,
private val activeSessionHolder: ActiveSessionHolder,
private val buildMeta: BuildMeta,
+ private val permissionChecker: PermissionChecker,
) : LocationListenerCompat {
private val locationManager = context.getSystemService()
@@ -173,7 +175,15 @@ class LocationTracker @Inject constructor(
fun removeCallback(callback: Callback) {
callbacks.remove(callback)
if (callbacks.size == 0) {
- stop()
+ if (permissionChecker.checkPermission(
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION,
+ )
+ ) {
+ stop()
+ } else {
+ Timber.w("Not allowed to use location api.")
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LiveLocationMapViewActivity.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LiveLocationMapViewActivity.kt
index 21e8f2ba029..2564d5a3959 100644
--- a/vector/src/main/java/im/vector/app/features/location/live/map/LiveLocationMapViewActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/location/live/map/LiveLocationMapViewActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.location.live.map
import android.content.Context
import android.content.Intent
import android.os.Parcelable
+import android.view.View
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.VectorBaseActivity
@@ -29,6 +30,9 @@ class LiveLocationMapViewActivity : VectorBaseActivity(initialState),
LocationSharingServiceConnection.Callback,
@@ -123,7 +127,15 @@ class LiveLocationMapViewModel @AssistedInject constructor(
copy(isLoadingUserLocation = true)
}
viewModelScope.launch(session.coroutineDispatchers.main) {
- locationTracker.start()
+ if (permissionChecker.checkPermission(
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION,
+ )
+ ) {
+ locationTracker.start()
+ } else {
+ Timber.w("Not allowed to use location api.")
+ }
locationTracker.requestLastKnownLocation()
}
}
diff --git a/vector/src/main/java/im/vector/app/features/location/live/tracking/LocationSharingAndroidService.kt b/vector/src/main/java/im/vector/app/features/location/live/tracking/LocationSharingAndroidService.kt
index 315a555703b..76205f98cfe 100644
--- a/vector/src/main/java/im/vector/app/features/location/live/tracking/LocationSharingAndroidService.kt
+++ b/vector/src/main/java/im/vector/app/features/location/live/tracking/LocationSharingAndroidService.kt
@@ -7,14 +7,18 @@
package im.vector.app.features.location.live.tracking
+import android.Manifest
import android.content.Intent
+import android.content.pm.PackageManager
import android.os.IBinder
import android.os.Parcelable
+import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationManagerCompat
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.extensions.startForegroundCompat
import im.vector.app.core.services.VectorAndroidService
+import im.vector.app.core.utils.PermissionChecker
import im.vector.app.features.location.LocationData
import im.vector.app.features.location.LocationTracker
import im.vector.app.features.location.live.GetLiveLocationShareSummaryUseCase
@@ -52,6 +56,7 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
@Inject lateinit var getLiveLocationShareSummaryUseCase: GetLiveLocationShareSummaryUseCase
@Inject lateinit var checkIfEventIsRedactedUseCase: CheckIfEventIsRedactedUseCase
+ @Inject lateinit var permissionChecker: PermissionChecker
private var binder: LocationSharingAndroidServiceBinder? = null
@@ -74,7 +79,15 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca
private fun initLocationTracking() {
// Start tracking location
locationTracker.addCallback(this)
- locationTracker.start()
+ if (permissionChecker.checkPermission(
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION,
+ )
+ ) {
+ locationTracker.start()
+ } else {
+ Timber.w("Not allowed to use location api.")
+ }
launchWithActiveSession { session ->
val job = locationTracker.locations
@@ -95,7 +108,11 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca
// Show a sticky notification
val notification = liveLocationNotificationBuilder.buildLiveLocationSharingNotification(roomArgs.roomId)
if (foregroundModeStarted) {
- NotificationManagerCompat.from(this).notify(FOREGROUND_SERVICE_NOTIFICATION_ID, notification)
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
+ Timber.w("Not allowed to notify.")
+ } else {
+ NotificationManagerCompat.from(this).notify(FOREGROUND_SERVICE_NOTIFICATION_ID, notification)
+ }
} else {
startForegroundCompat(FOREGROUND_SERVICE_NOTIFICATION_ID, notification)
foregroundModeStarted = true
@@ -146,10 +163,14 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca
}
private fun updateNotification() {
- if (liveInfoSet.isNotEmpty()) {
- val roomId = liveInfoSet.last().roomArgs.roomId
- val notification = liveLocationNotificationBuilder.buildLiveLocationSharingNotification(roomId)
- NotificationManagerCompat.from(this).notify(FOREGROUND_SERVICE_NOTIFICATION_ID, notification)
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
+ Timber.w("Not allowed to notify.")
+ } else {
+ if (liveInfoSet.isNotEmpty()) {
+ val roomId = liveInfoSet.last().roomArgs.roomId
+ val notification = liveLocationNotificationBuilder.buildLiveLocationSharingNotification(roomId)
+ NotificationManagerCompat.from(this).notify(FOREGROUND_SERVICE_NOTIFICATION_ID, notification)
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/location/preview/LocationPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/location/preview/LocationPreviewViewModel.kt
index aacff1f745f..ae091adaae1 100644
--- a/vector/src/main/java/im/vector/app/features/location/preview/LocationPreviewViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/location/preview/LocationPreviewViewModel.kt
@@ -7,6 +7,7 @@
package im.vector.app.features.location.preview
+import android.Manifest
import com.airbnb.mvrx.MavericksViewModelFactory
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -14,6 +15,7 @@ import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.platform.VectorViewModel
+import im.vector.app.core.utils.PermissionChecker
import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider
import im.vector.app.features.location.LocationData
import im.vector.app.features.location.LocationTracker
@@ -23,12 +25,14 @@ import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.util.MatrixItem
import org.matrix.android.sdk.api.util.toMatrixItem
+import timber.log.Timber
class LocationPreviewViewModel @AssistedInject constructor(
@Assisted private val initialState: LocationPreviewViewState,
private val session: Session,
private val locationPinProvider: LocationPinProvider,
private val locationTracker: LocationTracker,
+ private val permissionChecker: PermissionChecker,
) : VectorViewModel(initialState), LocationTracker.Callback {
@AssistedFactory
@@ -89,7 +93,15 @@ class LocationPreviewViewModel @AssistedInject constructor(
copy(isLoadingUserLocation = true)
}
viewModelScope.launch(session.coroutineDispatchers.main) {
- locationTracker.start()
+ if (permissionChecker.checkPermission(
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION,
+ )
+ ) {
+ locationTracker.start()
+ } else {
+ Timber.w("Not allowed to use location api.")
+ }
locationTracker.requestLastKnownLocation()
}
}
diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt
index cbf13acc986..2419ba7bfc1 100644
--- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt
@@ -76,6 +76,9 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
analyticsScreenName = MobileScreen.ScreenName.Login
diff --git a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt
index 05c331d1d04..57d631b5be7 100644
--- a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.media
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import androidx.core.net.toUri
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.di.ActiveSessionHolder
@@ -26,6 +27,9 @@ class BigImageViewerActivity : VectorBaseActivity
override fun getBinding() = ActivityBigImageViewerBinding.inflate(layoutInflater)
+ override val rootView: View
+ get() = views.mainRoot
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
diff --git a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt
index 058372feffd..e6e2209e421 100644
--- a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt
@@ -138,7 +138,9 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), AttachmentInt
}
}
+ @Suppress("DEPRECATION")
window.statusBarColor = ContextCompat.getColor(this, im.vector.lib.ui.styles.R.color.black_alpha)
+ @Suppress("DEPRECATION")
window.navigationBarColor = ContextCompat.getColor(this, im.vector.lib.ui.styles.R.color.black_alpha)
observeViewEvents()
diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDisplayer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDisplayer.kt
index 5106eb1dfcd..29eeb04f9d3 100644
--- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDisplayer.kt
+++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDisplayer.kt
@@ -7,18 +7,27 @@
package im.vector.app.features.notifications
+import android.Manifest
import android.app.Notification
import android.content.Context
+import android.content.pm.PackageManager
+import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationManagerCompat
import timber.log.Timber
import javax.inject.Inject
-class NotificationDisplayer @Inject constructor(context: Context) {
+class NotificationDisplayer @Inject constructor(
+ private val context: Context,
+) {
private val notificationManager = NotificationManagerCompat.from(context)
fun showNotificationMessage(tag: String?, id: Int, notification: Notification) {
- notificationManager.notify(tag, id, notification)
+ if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
+ Timber.w("Not allowed to notify.")
+ } else {
+ notificationManager.notify(tag, id, notification)
+ }
}
fun cancelNotificationMessage(tag: String?, id: Int) {
diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt
index 985d35961f5..aa6010c31ed 100755
--- a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt
+++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt
@@ -9,6 +9,7 @@
package im.vector.app.features.notifications
+import android.Manifest
import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationChannel
@@ -16,6 +17,7 @@ import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
+import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.net.Uri
@@ -27,6 +29,7 @@ import androidx.annotation.AttrRes
import androidx.annotation.ChecksSdkIntAtLeast
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
+import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.RemoteInput
@@ -153,55 +156,59 @@ class NotificationUtils @Inject constructor(
* Default notification importance: shows everywhere, makes noise, but does not visually
* intrude.
*/
- notificationManager.createNotificationChannel(NotificationChannel(
- NOISY_NOTIFICATION_CHANNEL_ID,
- stringProvider.getString(CommonStrings.notification_noisy_notifications).ifEmpty { "Noisy notifications" },
- NotificationManager.IMPORTANCE_DEFAULT
- )
- .apply {
- description = stringProvider.getString(CommonStrings.notification_noisy_notifications)
- enableVibration(true)
- enableLights(true)
- lightColor = accentColor
- })
+ notificationManager.createNotificationChannel(
+ NotificationChannel(
+ NOISY_NOTIFICATION_CHANNEL_ID,
+ stringProvider.getString(CommonStrings.notification_noisy_notifications).ifEmpty { "Noisy notifications" },
+ NotificationManager.IMPORTANCE_DEFAULT
+ )
+ .apply {
+ description = stringProvider.getString(CommonStrings.notification_noisy_notifications)
+ enableVibration(true)
+ enableLights(true)
+ lightColor = accentColor
+ })
/**
* Low notification importance: shows everywhere, but is not intrusive.
*/
- notificationManager.createNotificationChannel(NotificationChannel(
- SILENT_NOTIFICATION_CHANNEL_ID,
- stringProvider.getString(CommonStrings.notification_silent_notifications).ifEmpty { "Silent notifications" },
- NotificationManager.IMPORTANCE_LOW
- )
- .apply {
- description = stringProvider.getString(CommonStrings.notification_silent_notifications)
- setSound(null, null)
- enableLights(true)
- lightColor = accentColor
- })
-
- notificationManager.createNotificationChannel(NotificationChannel(
- LISTENING_FOR_EVENTS_NOTIFICATION_CHANNEL_ID,
- stringProvider.getString(CommonStrings.notification_listening_for_events).ifEmpty { "Listening for events" },
- NotificationManager.IMPORTANCE_MIN
- )
- .apply {
- description = stringProvider.getString(CommonStrings.notification_listening_for_events)
- setSound(null, null)
- setShowBadge(false)
- })
-
- notificationManager.createNotificationChannel(NotificationChannel(
- CALL_NOTIFICATION_CHANNEL_ID,
- stringProvider.getString(CommonStrings.call).ifEmpty { "Call" },
- NotificationManager.IMPORTANCE_HIGH
- )
- .apply {
- description = stringProvider.getString(CommonStrings.call)
- setSound(null, null)
- enableLights(true)
- lightColor = accentColor
- })
+ notificationManager.createNotificationChannel(
+ NotificationChannel(
+ SILENT_NOTIFICATION_CHANNEL_ID,
+ stringProvider.getString(CommonStrings.notification_silent_notifications).ifEmpty { "Silent notifications" },
+ NotificationManager.IMPORTANCE_LOW
+ )
+ .apply {
+ description = stringProvider.getString(CommonStrings.notification_silent_notifications)
+ setSound(null, null)
+ enableLights(true)
+ lightColor = accentColor
+ })
+
+ notificationManager.createNotificationChannel(
+ NotificationChannel(
+ LISTENING_FOR_EVENTS_NOTIFICATION_CHANNEL_ID,
+ stringProvider.getString(CommonStrings.notification_listening_for_events).ifEmpty { "Listening for events" },
+ NotificationManager.IMPORTANCE_MIN
+ )
+ .apply {
+ description = stringProvider.getString(CommonStrings.notification_listening_for_events)
+ setSound(null, null)
+ setShowBadge(false)
+ })
+
+ notificationManager.createNotificationChannel(
+ NotificationChannel(
+ CALL_NOTIFICATION_CHANNEL_ID,
+ stringProvider.getString(CommonStrings.call).ifEmpty { "Call" },
+ NotificationManager.IMPORTANCE_HIGH
+ )
+ .apply {
+ description = stringProvider.getString(CommonStrings.call)
+ setSound(null, null)
+ enableLights(true)
+ lightColor = accentColor
+ })
}
fun getChannel(channelId: String): NotificationChannel? {
@@ -997,7 +1004,11 @@ class NotificationUtils @Inject constructor(
}
fun showNotificationMessage(tag: String?, id: Int, notification: Notification) {
- notificationManager.notify(tag, id, notification)
+ if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
+ Timber.w("Not allowed to notify.")
+ } else {
+ notificationManager.notify(tag, id, notification)
+ }
}
fun cancelNotificationMessage(tag: String?, id: Int) {
@@ -1025,30 +1036,34 @@ class NotificationUtils @Inject constructor(
@SuppressLint("LaunchActivityFromNotification")
fun displayDiagnosticNotification() {
- val testActionIntent = Intent(context, TestNotificationReceiver::class.java)
- testActionIntent.action = actionIds.diagnostic
- val testPendingIntent = PendingIntent.getBroadcast(
- context,
- 0,
- testActionIntent,
- PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
- )
+ if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
+ Timber.w("Not allowed to notify.")
+ } else {
+ val testActionIntent = Intent(context, TestNotificationReceiver::class.java)
+ testActionIntent.action = actionIds.diagnostic
+ val testPendingIntent = PendingIntent.getBroadcast(
+ context,
+ 0,
+ testActionIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
+ )
- notificationManager.notify(
- "DIAGNOSTIC",
- 888,
- NotificationCompat.Builder(context, NOISY_NOTIFICATION_CHANNEL_ID)
- .setContentTitle(buildMeta.applicationName)
- .setContentText(stringProvider.getString(CommonStrings.settings_troubleshoot_test_push_notification_content))
- .setSmallIcon(R.drawable.ic_notification)
- .setLargeIcon(getBitmap(context, im.vector.lib.ui.styles.R.drawable.element_logo_green))
- .setColor(ContextCompat.getColor(context, im.vector.lib.ui.styles.R.color.notification_accent_color))
- .setPriority(NotificationCompat.PRIORITY_MAX)
- .setCategory(NotificationCompat.CATEGORY_STATUS)
- .setAutoCancel(true)
- .setContentIntent(testPendingIntent)
- .build()
- )
+ notificationManager.notify(
+ "DIAGNOSTIC",
+ 888,
+ NotificationCompat.Builder(context, NOISY_NOTIFICATION_CHANNEL_ID)
+ .setContentTitle(buildMeta.applicationName)
+ .setContentText(stringProvider.getString(CommonStrings.settings_troubleshoot_test_push_notification_content))
+ .setSmallIcon(R.drawable.ic_notification)
+ .setLargeIcon(getBitmap(context, im.vector.lib.ui.styles.R.drawable.element_logo_green))
+ .setColor(ContextCompat.getColor(context, im.vector.lib.ui.styles.R.color.notification_accent_color))
+ .setPriority(NotificationCompat.PRIORITY_MAX)
+ .setCategory(NotificationCompat.CATEGORY_STATUS)
+ .setAutoCancel(true)
+ .setContentIntent(testPendingIntent)
+ .build()
+ )
+ }
}
private fun getBitmap(context: Context, @DrawableRes drawableRes: Int): Bitmap? {
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingActivity.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingActivity.kt
index f62989fec61..dd8d287bad1 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.onboarding
import android.content.Context
import android.content.Intent
import android.net.Uri
+import android.view.View
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.lazyViewModel
import im.vector.app.core.extensions.validateBackPressed
@@ -33,6 +34,9 @@ class OnboardingActivity : VectorBaseActivity(), UnlockedA
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
onboardingVariant.onNewIntent(intent)
diff --git a/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt b/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt
index a002bc0329a..b5c70fddd94 100644
--- a/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt
@@ -9,6 +9,7 @@ package im.vector.app.features.pin
import android.content.Context
import android.content.Intent
+import android.view.View
import com.airbnb.mvrx.Mavericks
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
@@ -31,6 +32,9 @@ class PinActivity : VectorBaseActivity(), UnlockedActivit
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
if (isFirstCreation()) {
val fragmentArgs: PinArgs = intent?.extras?.getParcelableCompat(Mavericks.KEY_ARG) ?: return
diff --git a/vector/src/main/java/im/vector/app/features/pin/lockscreen/views/LockScreenCodeView.kt b/vector/src/main/java/im/vector/app/features/pin/lockscreen/views/LockScreenCodeView.kt
index 5187b8ba738..6efe59b09ad 100644
--- a/vector/src/main/java/im/vector/app/features/pin/lockscreen/views/LockScreenCodeView.kt
+++ b/vector/src/main/java/im/vector/app/features/pin/lockscreen/views/LockScreenCodeView.kt
@@ -92,7 +92,7 @@ class LockScreenCodeView @JvmOverloads constructor(
*/
fun deleteLast(): Int {
if (code.size == 0) return code.size
- code.removeLast()
+ code.removeAt(code.lastIndex)
getCodeView(code.size)?.toggle()
return code.size
}
diff --git a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt
index d2f8016bda8..5325a3f0435 100644
--- a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.qrcode
import android.app.Activity
import android.content.Intent
import android.os.Bundle
+import android.view.View
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import com.airbnb.mvrx.viewModel
@@ -26,6 +27,9 @@ class QrCodeScannerActivity : VectorBaseActivity() {
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
private val qrViewModel: QrCodeScannerViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt
index 71b58955739..b4024fa1242 100755
--- a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt
@@ -11,6 +11,7 @@ import android.content.Context
import android.content.Intent
import android.view.Menu
import android.view.MenuItem
+import android.view.View
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.core.widget.doOnTextChanged
@@ -37,6 +38,9 @@ class BugReportActivity :
private val viewModel: BugReportViewModel by viewModel()
+ override val rootView: View
+ get() = views.mainRoot
+
private var reportType: ReportType = ReportType.BUG_REPORT
override fun initUiAndData() {
diff --git a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt
index 7cd7b79b112..774b41245ce 100644
--- a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt
@@ -13,6 +13,7 @@ import android.graphics.Typeface
import android.util.TypedValue
import android.view.Menu
import android.view.MenuItem
+import android.view.View
import android.widget.SearchView
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
@@ -55,6 +56,9 @@ class EmojiReactionPickerActivity :
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun getTitleRes() = CommonStrings.title_activity_emoji_reaction_picker
@Inject lateinit var emojiCompatFontProvider: EmojiCompatFontProvider
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt
index 3940404af96..8a1c75ad61b 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.roomdirectory
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.viewModel
import com.airbnb.mvrx.withState
@@ -41,6 +42,9 @@ class RoomDirectoryActivity : VectorBaseActivity(), Matri
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
analyticsScreenName = MobileScreen.ScreenName.RoomDirectory
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt
index c3ba0e70413..90be84d8480 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt
@@ -11,6 +11,7 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.Mavericks
import dagger.hilt.android.AndroidEntryPoint
@@ -36,6 +37,9 @@ class CreateRoomActivity : VectorBaseActivity() {
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
if (isFirstCreation()) {
val fragmentArgs: CreateRoomArgs = intent?.extras?.getParcelableCompat(Mavericks.KEY_ARG) ?: return
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt
index 77bac7dfa18..b6859f36dff 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.roomdirectory.roompreview
import android.content.Context
import android.content.Intent
import android.os.Parcelable
+import android.view.View
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.VectorBaseActivity
@@ -73,6 +74,9 @@ class RoomPreviewActivity : VectorBaseActivity() {
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.simpleFragmentContainer
+
override fun initUiAndData() {
if (isFirstCreation()) {
val args = intent.getParcelableExtraCompat(ARG)
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt
index cf593c039e9..43ee03fd589 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt
@@ -9,6 +9,7 @@ package im.vector.app.features.roommemberprofile
import android.content.Context
import android.content.Intent
+import android.view.View
import android.widget.Toast
import com.airbnb.mvrx.Mavericks
import com.airbnb.mvrx.viewModel
@@ -37,6 +38,11 @@ class RoomMemberProfileActivity : VectorBaseActivity() {
return ActivitySimpleBinding.inflate(layoutInflater)
}
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
if (isFirstCreation()) {
val fragmentArgs: RoomMemberProfileArgs = intent?.extras?.getParcelableCompat(Mavericks.KEY_ARG) ?: return
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt
index 5bbfab6e18d..db5cd3b9cb1 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt
@@ -9,6 +9,7 @@ package im.vector.app.features.roomprofile
import android.content.Context
import android.content.Intent
+import android.view.View
import android.widget.Toast
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.Mavericks
@@ -68,6 +69,9 @@ class RoomProfileActivity :
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
sharedActionViewModel = viewModelProvider.get(RoomProfileSharedActionViewModel::class.java)
roomProfileArgs = intent?.extras?.getParcelableCompat(Mavericks.KEY_ARG) ?: return
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/detail/ui/RoomPollDetailActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/detail/ui/RoomPollDetailActivity.kt
index dc3db0401e6..a8a1c318627 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/detail/ui/RoomPollDetailActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/detail/ui/RoomPollDetailActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.roomprofile.polls.detail.ui
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import com.airbnb.mvrx.Mavericks
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
@@ -25,6 +26,11 @@ class RoomPollDetailActivity : VectorBaseActivity() {
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt
index 30d2e688b66..868564737fb 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.roomprofile.settings.joinrule
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import androidx.core.view.isVisible
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
@@ -40,6 +41,11 @@ class RoomJoinRuleActivity : VectorBaseActivity() {
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+
+ override val rootView: View
+ get() = views.coordinatorLayout
+
private lateinit var roomProfileArgs: RoomProfileArgs
val viewModel: RoomJoinRuleChooseRestrictedViewModel by viewModel()
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt
index 62d09174906..c942d8f06ad 100755
--- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt
@@ -11,6 +11,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Parcelable
+import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.preference.Preference
@@ -47,6 +48,9 @@ class VectorSettingsActivity : VectorBaseActivity
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun getTitleRes() = CommonStrings.title_activity_settings
private var keyToHighlight: String? = null
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/rename/RenameSessionActivity.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/rename/RenameSessionActivity.kt
index 3625dee311d..7a556e18ebc 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/rename/RenameSessionActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/rename/RenameSessionActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.settings.devices.v2.rename
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import android.view.WindowManager
import com.airbnb.mvrx.Mavericks
import dagger.hilt.android.AndroidEntryPoint
@@ -26,6 +27,11 @@ class RenameSessionActivity : VectorBaseActivity() {
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
diff --git a/vector/src/main/java/im/vector/app/features/settings/font/FontScaleSettingActivity.kt b/vector/src/main/java/im/vector/app/features/settings/font/FontScaleSettingActivity.kt
index d2e8ffccbfa..1ffb93d840b 100644
--- a/vector/src/main/java/im/vector/app/features/settings/font/FontScaleSettingActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/font/FontScaleSettingActivity.kt
@@ -7,6 +7,7 @@
package im.vector.app.features.settings.font
+import android.view.View
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.VectorBaseActivity
@@ -17,6 +18,11 @@ class FontScaleSettingActivity : VectorBaseActivity() {
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun initUiAndData() {
if (isFirstCreation()) {
addFragment(views.simpleFragmentContainer, FontScaleSettingFragment::class.java)
diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareActivity.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareActivity.kt
index e2a00c516fe..3d89a6ebc9c 100644
--- a/vector/src/main/java/im/vector/app/features/share/IncomingShareActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareActivity.kt
@@ -9,6 +9,7 @@ package im.vector.app.features.share
import android.content.Intent
import android.os.Bundle
+import android.view.View
import com.airbnb.mvrx.viewModel
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
@@ -46,6 +47,9 @@ class IncomingShareActivity : VectorBaseActivity() {
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
private fun handleAppStarted() {
// If we are not logged in, stop the sharing process and open login screen.
// In the future, we might want to relaunch the sharing process after login.
diff --git a/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt b/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt
index c94d9ab7b92..e6b3b817ea7 100644
--- a/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.signout.hard
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivitySignedOutBinding
@@ -26,6 +27,9 @@ class SignedOutActivity : VectorBaseActivity() {
override fun getBinding() = ActivitySignedOutBinding.inflate(layoutInflater)
+ override val rootView: View
+ get() = views.signedOut
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt
index 5f060adeb9d..7e5d776ca2d 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt
@@ -11,6 +11,7 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.airbnb.mvrx.Mavericks
@@ -38,6 +39,11 @@ class SpaceExploreActivity : VectorBaseActivity(), Matrix
override fun getBinding(): ActivitySimpleBinding = ActivitySimpleBinding.inflate(layoutInflater)
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun getTitleRes(): Int = CommonStrings.space_explore_activity_title
val sharedViewModel: SpaceDirectoryViewModel by viewModel()
diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpacePreviewActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/SpacePreviewActivity.kt
index d698f2ed358..6b60253b4a1 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/SpacePreviewActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/SpacePreviewActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.spaces
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.Mavericks
import dagger.hilt.android.AndroidEntryPoint
@@ -29,6 +30,11 @@ class SpacePreviewActivity : VectorBaseActivity() {
override fun getBinding(): ActivitySimpleBinding = ActivitySimpleBinding.inflate(layoutInflater)
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sharedActionViewModel = viewModelProvider.get(SpacePreviewSharedActionViewModel::class.java)
diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt
index cf7b706adfd..84c3c78b2ae 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.spaces.leave
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import androidx.core.view.isGone
import androidx.core.view.isVisible
import com.airbnb.mvrx.Fail
@@ -33,6 +34,11 @@ class SpaceLeaveAdvancedActivity : VectorBaseActivity() {
override fun getBinding(): ActivitySimpleLoadingBinding = ActivitySimpleLoadingBinding.inflate(layoutInflater)
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+
+ override val rootView: View
+ get() = views.coordinatorLayout
+
override fun getTitleRes(): Int = CommonStrings.space_add_existing_rooms
val sharedViewModel: SpaceManageSharedViewModel by viewModel()
diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt
index 7a12dedd56e..4bb2f0c44a8 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt
@@ -10,6 +10,7 @@ package im.vector.app.features.spaces.people
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.view.View
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
@@ -32,6 +33,11 @@ class SpacePeopleActivity : VectorBaseActivity() {
override fun getBinding() = ActivitySimpleLoadingBinding.inflate(layoutInflater)
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+
+ override val rootView: View
+ get() = views.coordinatorLayout
+
private lateinit var sharedActionViewModel: SpacePeopleSharedActionViewModel
override fun initUiAndData() {
diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt
index 06fc143e21c..7b27ffdd1ee 100644
--- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt
@@ -11,6 +11,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Parcelable
+import android.view.View
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.view.isVisible
@@ -51,6 +52,9 @@ class UserCodeActivity : VectorBaseActivity(),
override fun getCoordinatorLayout() = views.coordinatorLayout
+ override val rootView: View
+ get() = views.coordinatorLayout
+
private val fragmentLifecycleCallbacks = object : FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentResumed(fm: FragmentManager, f: Fragment) {
if (f is MatrixToBottomSheet) {
diff --git a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderL.kt b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderL.kt
index f53571e753f..b905ff4447a 100644
--- a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderL.kt
+++ b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderL.kt
@@ -7,6 +7,7 @@
package im.vector.app.features.voice
+import android.Manifest
import android.content.Context
import android.media.AudioFormat
import android.media.AudioRecord
@@ -15,6 +16,7 @@ import android.media.audiofx.AutomaticGainControl
import android.media.audiofx.NoiseSuppressor
import android.os.Build
import android.widget.Toast
+import im.vector.app.core.utils.PermissionChecker
import io.element.android.opusencoder.OggOpusEncoder
import io.element.android.opusencoder.configuration.SampleRate
import kotlinx.coroutines.CoroutineScope
@@ -22,6 +24,7 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.extensions.tryOrNull
+import timber.log.Timber
import kotlin.coroutines.CoroutineContext
/**
@@ -31,6 +34,7 @@ class VoiceRecorderL(
private val context: Context,
coroutineContext: CoroutineContext,
private val codec: OggOpusEncoder,
+ private val permissionChecker: PermissionChecker,
) : AbstractVoiceRecorder(context) {
companion object {
@@ -127,7 +131,11 @@ class VoiceRecorderL(
bufferSizeInShorts = AudioRecord.getMinBufferSize(SAMPLE_RATE.value, channelConfig, format)
// Buffer is created as a ShortArray, but AudioRecord needs the size in bytes
val bufferSizeInBytes = bufferSizeInShorts * 2
- audioRecorder = AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE.value, channelConfig, format, bufferSizeInBytes)
+ if (permissionChecker.checkPermission(Manifest.permission.RECORD_AUDIO)) {
+ audioRecorder = AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE.value, channelConfig, format, bufferSizeInBytes)
+ } else {
+ Timber.w("Not allowed to record audio.")
+ }
}
private fun calculateMaxAmplitude(buffer: ShortArray) {
diff --git a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderProvider.kt b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderProvider.kt
index 0b971907a2e..62309aa59b1 100644
--- a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderProvider.kt
+++ b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderProvider.kt
@@ -13,6 +13,7 @@ import android.media.MediaFormat
import android.os.Build
import androidx.annotation.ChecksSdkIntAtLeast
import androidx.annotation.VisibleForTesting
+import im.vector.app.core.utils.PermissionChecker
import im.vector.app.features.VectorFeatures
import io.element.android.opusencoder.OggOpusEncoder
import kotlinx.coroutines.Dispatchers
@@ -23,12 +24,13 @@ class VoiceRecorderProvider @Inject constructor(
private val context: Context,
private val vectorFeatures: VectorFeatures,
private val buildVersionSdkIntProvider: BuildVersionSdkIntProvider,
+ private val permissionChecker: PermissionChecker,
) {
fun provideVoiceRecorder(): VoiceRecorder {
return if (useNativeRecorder()) {
VoiceRecorderQ(context)
} else {
- VoiceRecorderL(context, Dispatchers.IO, OggOpusEncoder.create())
+ VoiceRecorderL(context, Dispatchers.IO, OggOpusEncoder.create(), permissionChecker)
}
}
diff --git a/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt b/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt
index 7af0dc62dc8..6e7cb9e4684 100644
--- a/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt
@@ -9,6 +9,7 @@ package im.vector.app.features.webview
import android.content.Context
import android.content.Intent
+import android.view.View
import android.webkit.WebChromeClient
import android.webkit.WebView
import dagger.hilt.android.AndroidEntryPoint
@@ -28,6 +29,9 @@ class VectorWebViewActivity : VectorBaseActivity()
override fun getBinding() = ActivityVectorWebViewBinding.inflate(layoutInflater)
+ override val rootView: View
+ get() = views.mainRoot
+
val session: Session by lazy {
activeSessionHolder.getActiveSession()
}
diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt
index 099f39f67a7..917fc02440b 100644
--- a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt
@@ -20,6 +20,7 @@ import android.content.IntentFilter
import android.graphics.drawable.Icon
import android.os.Build
import android.util.Rational
+import android.view.View
import androidx.annotation.RequiresApi
import androidx.core.app.PictureInPictureModeChangedInfo
import androidx.core.content.ContextCompat
@@ -77,6 +78,9 @@ class WidgetActivity : VectorBaseActivity() {
override fun getBinding() = ActivityWidgetBinding.inflate(layoutInflater)
+ override val rootView: View
+ get() = views.mainRoot
+
override fun getTitleRes() = CommonStrings.room_widget_activity_title
override fun initUiAndData() {
diff --git a/vector/src/main/res/layout/activity_big_image_viewer.xml b/vector/src/main/res/layout/activity_big_image_viewer.xml
index 8f1cf88affa..cd254db50db 100644
--- a/vector/src/main/res/layout/activity_big_image_viewer.xml
+++ b/vector/src/main/res/layout/activity_big_image_viewer.xml
@@ -1,6 +1,7 @@
@@ -28,4 +29,4 @@
app:layout_constraintTop_toBottomOf="@id/appBarLayout"
app:optimizeDisplay="true" />
-
\ No newline at end of file
+
diff --git a/vector/src/main/res/layout/activity_bug_report.xml b/vector/src/main/res/layout/activity_bug_report.xml
index 1c019c858d5..799ab2fb5f5 100644
--- a/vector/src/main/res/layout/activity_bug_report.xml
+++ b/vector/src/main/res/layout/activity_bug_report.xml
@@ -2,6 +2,7 @@
diff --git a/vector/src/main/res/layout/activity_call.xml b/vector/src/main/res/layout/activity_call.xml
index 5734e5f92ab..02c90f8e547 100644
--- a/vector/src/main/res/layout/activity_call.xml
+++ b/vector/src/main/res/layout/activity_call.xml
@@ -97,7 +97,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
- android:fitsSystemWindows="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
diff --git a/vector/src/main/res/layout/activity_location_sharing.xml b/vector/src/main/res/layout/activity_location_sharing.xml
index bbb46de8c76..9e44c72c831 100755
--- a/vector/src/main/res/layout/activity_location_sharing.xml
+++ b/vector/src/main/res/layout/activity_location_sharing.xml
@@ -1,5 +1,6 @@
@@ -21,4 +22,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
-
\ No newline at end of file
+
diff --git a/vector/src/main/res/layout/activity_main.xml b/vector/src/main/res/layout/activity_main.xml
index ba5925f000d..626eb100d4f 100644
--- a/vector/src/main/res/layout/activity_main.xml
+++ b/vector/src/main/res/layout/activity_main.xml
@@ -3,6 +3,7 @@
diff --git a/vector/src/main/res/layout/activity_widget.xml b/vector/src/main/res/layout/activity_widget.xml
index b278bb5a1aa..f1222d11df1 100755
--- a/vector/src/main/res/layout/activity_widget.xml
+++ b/vector/src/main/res/layout/activity_widget.xml
@@ -1,6 +1,7 @@
@@ -23,4 +24,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
-
\ No newline at end of file
+
diff --git a/vector/src/main/res/layout/fragment_generic_recycler.xml b/vector/src/main/res/layout/fragment_generic_recycler.xml
index 472f05092e7..1c2eb2fc40f 100644
--- a/vector/src/main/res/layout/fragment_generic_recycler.xml
+++ b/vector/src/main/res/layout/fragment_generic_recycler.xml
@@ -2,6 +2,7 @@
diff --git a/vector/src/main/res/layout/fragment_new_home_detail.xml b/vector/src/main/res/layout/fragment_new_home_detail.xml
index d20223a3823..32d1dfc5d21 100644
--- a/vector/src/main/res/layout/fragment_new_home_detail.xml
+++ b/vector/src/main/res/layout/fragment_new_home_detail.xml
@@ -45,7 +45,6 @@
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:fitsSystemWindows="true"
app:layout_constraintTop_toBottomOf="@id/syncStateView">