mirror of
https://github.com/vector-im/riotX-android
synced 2025-10-05 15:52:47 +02:00
Merge pull request #9051 from element-hq/feature/bma/target35
Change targetApi to 35
This commit is contained in:
@@ -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"
|
||||
|
@@ -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
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -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
|
||||
|
37
gradlew
vendored
37
gradlew
vendored
@@ -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.
|
||||
|
26
gradlew.bat
vendored
26
gradlew.bat
vendored
@@ -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
|
||||
|
@@ -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")
|
||||
|
@@ -64,6 +64,9 @@
|
||||
|
||||
<!-- Material color -->
|
||||
<item name="colorPrimary">@color/element_accent_light</item>
|
||||
<!-- Fix background color of status bar in home and room detail activity -->
|
||||
<!--item name="colorPrimaryDark">@color/element_background_light</item-->
|
||||
<item name="colorPrimaryDark">?vctr_toolbar_background</item>
|
||||
<item name="colorPrimaryVariant">@color/element_accent_light</item>
|
||||
<item name="colorOnPrimary">@android:color/white</item>
|
||||
<item name="colorSecondary">@color/element_accent_light</item>
|
||||
|
@@ -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.
|
||||
|
@@ -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<ActivityDebugMenuBinding>() {
|
||||
|
||||
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
|
||||
|
@@ -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<ActivityDebugPermissionBindin
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
// For debug
|
||||
private val allPermissions = listOf(
|
||||
Manifest.permission.CAMERA,
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
package im.vector.app.features.debug.analytics
|
||||
|
||||
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 DebugAnalyticsActivity : VectorBaseActivity<ActivitySimpleBinding>() {
|
||||
|
||||
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
addFragment(
|
||||
|
@@ -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<FragmentGenericRecycler
|
||||
|
||||
override fun getBinding() = FragmentGenericRecyclerBinding.inflate(layoutInflater)
|
||||
|
||||
override val rootView: View
|
||||
get() = views.mainRoot
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
controller.listener = object : FeaturesController.Listener {
|
||||
|
@@ -8,6 +8,7 @@
|
||||
package im.vector.app.features.debug.jitsi
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.View
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.application.databinding.ActivityDebugJitsiBinding
|
||||
@@ -19,6 +20,8 @@ class DebugJitsiActivity : VectorBaseActivity<ActivityDebugJitsiBinding>() {
|
||||
override fun getBinding() = ActivityDebugJitsiBinding.inflate(layoutInflater)
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun initUiAndData() {
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
addFragment(
|
||||
|
@@ -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<ActivitySimpleBinding>()
|
||||
|
||||
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
addFragment(
|
||||
|
@@ -167,8 +167,7 @@
|
||||
|
||||
<activity
|
||||
android:name=".features.home.room.detail.RoomDetailActivity"
|
||||
android:parentActivityName=".features.home.HomeActivity"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
android:parentActivityName=".features.home.HomeActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".features.home.HomeActivity" />
|
||||
@@ -369,8 +368,8 @@
|
||||
|
||||
<service
|
||||
android:name=".core.services.CallAndroidService"
|
||||
android:foregroundServiceType="phoneCall"
|
||||
android:exported="false">
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="phoneCall">
|
||||
<!-- in order to get headset button events -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MEDIA_BUTTON" />
|
||||
@@ -387,7 +386,8 @@
|
||||
<service
|
||||
android:name=".features.call.telecom.VectorConnectionAndroidService"
|
||||
android:exported="false"
|
||||
android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
|
||||
android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
|
||||
tools:targetApi="M">
|
||||
<intent-filter>
|
||||
<action android:name="android.telecom.ConnectionService" />
|
||||
</intent-filter>
|
||||
@@ -413,8 +413,7 @@
|
||||
android:name=".features.call.audio.MicrophoneAccessService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="microphone"
|
||||
android:permission="android.permission.FOREGROUND_SERVICE_MICROPHONE">
|
||||
</service>
|
||||
android:permission="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
|
||||
|
||||
<!-- Receivers -->
|
||||
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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<ActivityBinding>() {
|
||||
|
||||
final override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
override fun initUiAndData() {
|
||||
setupToolbar(views.toolbar)
|
||||
.allowBack(true)
|
||||
|
@@ -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<VB : ViewBinding> : 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<VB : ViewBinding> : 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<VB : ViewBinding> : 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<VB : ViewBinding> : 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<VB : ViewBinding> : AppCompatActivity(), Maver
|
||||
mdmService.unregisterListener(this)
|
||||
}
|
||||
|
||||
override fun onWindowFocusChanged(hasFocus: Boolean) {
|
||||
super.onWindowFocusChanged(hasFocus)
|
||||
|
||||
if (hasFocus && displayInFullscreen()) {
|
||||
setFullScreen()
|
||||
}
|
||||
}
|
||||
|
||||
private val onMultiWindowModeChangedListener = Consumer<MultiWindowModeChangedInfo> {
|
||||
Timber.w("onMultiWindowModeChanged. isInMultiWindowMode: ${it.isInMultiWindowMode}")
|
||||
bugReporter.inMultiWindowMode = it.isInMultiWindowMode
|
||||
@@ -461,30 +472,6 @@ abstract class VectorBaseActivity<VB : ViewBinding> : 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<VB : ViewBinding> : 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<VB : ViewBinding> : AppCompatActivity(), Maver
|
||||
|
||||
open fun getCoordinatorLayout(): CoordinatorLayout? = null
|
||||
|
||||
abstract val rootView: View
|
||||
|
||||
/* ==========================================================================================
|
||||
* User Consent
|
||||
* ========================================================================================== */
|
||||
|
@@ -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>(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,
|
||||
|
@@ -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<CallArgs>(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
|
||||
}
|
||||
|
@@ -658,7 +658,8 @@ class ExpandingBottomSheetBehavior<V : View> : CoordinatorLayout.Behavior<V> {
|
||||
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
|
||||
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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<ActivityMainBinding>(), UnlockedActivity
|
||||
val className = componentName.className
|
||||
return packageName == buildMeta.applicationId && className in allowList
|
||||
}
|
||||
|
||||
override val rootView: View
|
||||
get() = views.mainRoot
|
||||
}
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
override fun initUiAndData() {
|
||||
orientationLocker.lockPhonesToPortrait(this)
|
||||
if (isFirstCreation()) {
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
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
|
||||
|
@@ -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")
|
||||
|
@@ -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()
|
||||
|
@@ -43,6 +43,11 @@ internal class API21AudioDeviceDetector(
|
||||
return HashSet<CallAudioManager.Device>().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))
|
||||
}
|
||||
}
|
||||
|
@@ -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<ActivityJitsiBinding>(), 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()
|
||||
|
@@ -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<View>(R.id.zero).setOnClickListener { keyPressed(KeyEvent.KEYCODE_0, "0") }
|
||||
dialpadView.findViewById<View>(R.id.one).setOnClickListener { keyPressed(KeyEvent.KEYCODE_1, "1") }
|
||||
|
@@ -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<ActivityCallTransferBinding>() {
|
||||
|
||||
override fun getCoordinatorLayout() = views.vectorCoordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.vectorCoordinatorLayout
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
waitingView = views.waitingView.waitingView
|
||||
|
@@ -122,6 +122,7 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetBoot
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
val rootView = super.onCreateView(inflater, container, savedInstanceState)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
@Suppress("DEPRECATION")
|
||||
dialog?.window?.setDecorFitsSystemWindows(false)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
|
@@ -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?) {
|
||||
|
@@ -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)
|
||||
|
@@ -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() {
|
||||
|
@@ -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<ActivitySearchBinding>() {
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setupToolbar(views.searchToolbar)
|
||||
|
@@ -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<ActivityFilteredRoomsBinding>()
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
analyticsScreenName = MobileScreen.ScreenName.RoomFilter
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
addFragment(views.simpleFragmentContainer, InvitesFragment::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
}
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
override fun initUiAndData() {
|
||||
orientationLocker.lockPhonesToPortrait(this)
|
||||
if (isFirstCreation()) {
|
||||
|
@@ -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<ActivityThreadsBinding>() {
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
initFragment()
|
||||
|
@@ -32,7 +32,7 @@ class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager
|
||||
/**
|
||||
* The activities information collected from the app manifest.
|
||||
*/
|
||||
private var activitiesInfo: Array<ActivityInfo> = emptyArray()
|
||||
private var activitiesInfo: List<ActivityInfo>? = 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 }
|
||||
}
|
||||
|
@@ -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<ActivityProgressBinding>() {
|
||||
|
||||
override fun getBinding() = ActivityProgressBinding.inflate(layoutInflater)
|
||||
|
||||
override val rootView: View
|
||||
get() = views.mainRoot
|
||||
|
||||
override fun initUiAndData() {
|
||||
handleIntent()
|
||||
}
|
||||
|
@@ -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<ActivityLocationSharingBindin
|
||||
|
||||
override fun getBinding() = ActivityLocationSharingBinding.inflate(layoutInflater)
|
||||
|
||||
override val rootView: View
|
||||
get() = views.mainRoot
|
||||
|
||||
override fun initUiAndData() {
|
||||
val locationSharingArgs: LocationSharingArgs? = intent?.extras?.getParcelableCompat(EXTRA_LOCATION_SHARING_ARGS)
|
||||
if (locationSharingArgs == null) {
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
package im.vector.app.features.location
|
||||
|
||||
import android.Manifest
|
||||
import android.graphics.drawable.Drawable
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import dagger.assisted.Assisted
|
||||
@@ -15,6 +16,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.domain.usecase.CompareLocationsUseCase
|
||||
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
|
||||
@@ -48,6 +50,7 @@ class LocationSharingViewModel @AssistedInject constructor(
|
||||
private val session: Session,
|
||||
private val compareLocationsUseCase: CompareLocationsUseCase,
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val permissionChecker: PermissionChecker,
|
||||
) : VectorViewModel<LocationSharingViewState, LocationSharingAction, LocationSharingViewEvents>(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() {
|
||||
|
@@ -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<LocationManager>()
|
||||
@@ -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.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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<ActivityLocationSharingBi
|
||||
|
||||
override fun getBinding() = ActivityLocationSharingBinding.inflate(layoutInflater)
|
||||
|
||||
override val rootView: View
|
||||
get() = views.mainRoot
|
||||
|
||||
override fun initUiAndData() {
|
||||
val mapViewArgs: LiveLocationMapViewArgs? = intent?.extras?.getParcelableCompat(EXTRA_LIVE_LOCATION_MAP_VIEW_ARGS)
|
||||
if (mapViewArgs == null) {
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
package im.vector.app.features.location.live.map
|
||||
|
||||
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.location.LocationData
|
||||
import im.vector.app.features.location.LocationTracker
|
||||
import im.vector.app.features.location.live.StopLiveLocationShareUseCase
|
||||
@@ -23,6 +25,7 @@ import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.room.location.UpdateLiveLocationShareResult
|
||||
import timber.log.Timber
|
||||
|
||||
class LiveLocationMapViewModel @AssistedInject constructor(
|
||||
@Assisted private val initialState: LiveLocationMapViewState,
|
||||
@@ -31,6 +34,7 @@ class LiveLocationMapViewModel @AssistedInject constructor(
|
||||
private val locationSharingServiceConnection: LocationSharingServiceConnection,
|
||||
private val stopLiveLocationShareUseCase: StopLiveLocationShareUseCase,
|
||||
private val locationTracker: LocationTracker,
|
||||
private val permissionChecker: PermissionChecker,
|
||||
) :
|
||||
VectorViewModel<LiveLocationMapViewState, LiveLocationMapAction, LiveLocationMapViewEvents>(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()
|
||||
}
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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<LocationPreviewViewState, LocationPreviewAction, LocationPreviewViewEvents>(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()
|
||||
}
|
||||
}
|
||||
|
@@ -76,6 +76,9 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), UnlockedA
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
override fun initUiAndData() {
|
||||
analyticsScreenName = MobileScreen.ScreenName.Login
|
||||
|
||||
|
@@ -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<ActivityBigImageViewerBinding>
|
||||
|
||||
override fun getBinding() = ActivityBigImageViewerBinding.inflate(layoutInflater)
|
||||
|
||||
override val rootView: View
|
||||
get() = views.mainRoot
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
@@ -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()
|
||||
|
@@ -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) {
|
||||
|
@@ -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(
|
||||
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(
|
||||
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(
|
||||
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? {
|
||||
|
@@ -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<ActivityLoginBinding>(), UnlockedA
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
onboardingVariant.onNewIntent(intent)
|
||||
|
@@ -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<ActivitySimpleBinding>(), 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
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
private val qrViewModel: QrCodeScannerViewModel by viewModel()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
@@ -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() {
|
||||
|
@@ -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
|
||||
|
@@ -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<ActivitySimpleBinding>(), 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
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
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
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.simpleFragmentContainer
|
||||
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
val args = intent.getParcelableExtraCompat<RoomPreviewData>(ARG)
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
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
|
||||
|
@@ -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
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
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)
|
||||
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
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()
|
||||
|
@@ -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<ActivityVectorSettingsBinding>
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
override fun getTitleRes() = CommonStrings.title_activity_settings
|
||||
|
||||
private var keyToHighlight: String? = null
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
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)
|
||||
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
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)
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
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.
|
||||
|
@@ -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<ActivitySignedOutBinding>() {
|
||||
|
||||
override fun getBinding() = ActivitySignedOutBinding.inflate(layoutInflater)
|
||||
|
||||
override val rootView: View
|
||||
get() = views.signedOut
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
@@ -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<ActivitySimpleBinding>(), 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()
|
||||
|
@@ -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<ActivitySimpleBinding>() {
|
||||
|
||||
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)
|
||||
|
@@ -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<ActivitySimpleLoadingBindi
|
||||
|
||||
override fun getBinding(): ActivitySimpleLoadingBinding = ActivitySimpleLoadingBinding.inflate(layoutInflater)
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override val rootView: View
|
||||
get() = views.coordinatorLayout
|
||||
|
||||
private val leaveViewModel: SpaceLeaveAdvancedViewModel by viewModel()
|
||||
|
||||
override fun showWaitingView(text: String?) {
|
||||
|
@@ -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.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
@@ -49,6 +50,11 @@ class SpaceManageActivity : VectorBaseActivity<ActivitySimpleLoadingBinding>() {
|
||||
|
||||
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()
|
||||
|
@@ -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<ActivitySimpleLoadingBinding>() {
|
||||
|
||||
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() {
|
||||
|
@@ -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<ActivitySimpleBinding>(),
|
||||
|
||||
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) {
|
||||
|
@@ -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) {
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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<ActivityVectorWebViewBinding>()
|
||||
|
||||
override fun getBinding() = ActivityVectorWebViewBinding.inflate(layoutInflater)
|
||||
|
||||
override val rootView: View
|
||||
get() = views.mainRoot
|
||||
|
||||
val session: Session by lazy {
|
||||
activeSessionHolder.getActiveSession()
|
||||
}
|
||||
|
@@ -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<ActivityWidgetBinding>() {
|
||||
|
||||
override fun getBinding() = ActivityWidgetBinding.inflate(layoutInflater)
|
||||
|
||||
override val rootView: View
|
||||
get() = views.mainRoot
|
||||
|
||||
override fun getTitleRes() = CommonStrings.room_widget_activity_title
|
||||
|
||||
override fun initUiAndData() {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/mainRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
@@ -28,4 +29,4 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/appBarLayout"
|
||||
app:optimizeDisplay="true" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/mainRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
@@ -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"
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/mainRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
@@ -21,4 +22,4 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@@ -3,6 +3,7 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/mainRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:background="@drawable/splash"
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/mainRoot"
|
||||
android:background="?vctr_waiting_background_color">
|
||||
|
||||
<ProgressBar
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/mainRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".features.webview.VectorWebViewActivity">
|
||||
|
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/mainRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
@@ -23,4 +24,4 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/mainRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:colorBackground">
|
||||
|
@@ -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">
|
||||
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
|
@@ -25,7 +25,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="4dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:background="?android:colorBackground"
|
||||
app:layout_constraintBottom_toTopOf="@id/roomPollsViewPager"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
Reference in New Issue
Block a user