Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ steps:

- label: "ktlint"
command:
- "curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.34.2/ktlint && chmod a+x ktlint"
- "curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.36.0/ktlint && chmod a+x ktlint"
- "./ktlint --android --experimental -v"
plugins:
- docker#v3.1.0:
Expand Down
3 changes: 2 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ SDK API changes ⚠️:
-

Build 🧱:
-
- Upgrade ktlint to version 0.36.0

Other changes:
- Restore availability to Chromebooks (#932)
- Add a [documentation](./docs/integration_tests.md) to run integration tests

Changes in RiotX 0.17.0 (2020-02-27)
Expand Down
13 changes: 12 additions & 1 deletion vector/lint.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
<issue id="MissingTranslation" severity="warning" />
<issue id="TypographyEllipsis" severity="error" />
<issue id="ImpliedQuantity" severity="warning" />
<issue id="IconXmlAndPng" severity="error" />
<issue id="IconDipSize" severity="error" />
<issue id="IconDuplicatesConfig" severity="error" />
<issue id="IconDuplicates" severity="error" />
<issue id="IconExpectedSize" severity="error" />

<!-- UX -->
<issue id="ButtonOrder" severity="error" />
Expand All @@ -19,6 +24,7 @@
<issue id="InefficientWeight" severity="error" />
<issue id="DisableBaselineAlignment" severity="error" />
<issue id="ScrollViewSize" severity="error" />
<issue id="NegativeMargin" severity="error" />

<!-- RTL -->
<issue id="RtlEnabled" severity="error" />
Expand All @@ -30,9 +36,14 @@
<issue id="SetTextI18n" severity="error" />
<issue id="ViewConstructor" severity="error" />
<issue id="UseValueOf" severity="error" />
<issue id="Recycle" severity="error" />
<issue id="KotlinPropertyAccess" severity="error" />

<!-- Ignore error from HtmlCompressor lib -->
<issue id="InvalidPackage">
<ignore path="**/htmlcompressor-1.4.jar"/>
<ignore path="**/htmlcompressor-1.4.jar" />
</issue>

<!-- Manifest -->
<issue id="PermissionImpliesUnsupportedChromeOsHardware" severity="error" />
</lint>
9 changes: 9 additions & 0 deletions vector/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />

<!-- Adding CAMERA permission prevents Chromebooks to see the application on the PlayStore -->
<!-- Tell that the Camera is not mandatory to install the application -->
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />

<application
android:name=".VectorApplication"
android:allowBackup="false"
Expand Down
46 changes: 46 additions & 0 deletions vector/src/main/java/im/vector/riotx/core/hardware/HardwareInfo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

@file:Suppress("DEPRECATION")

package im.vector.riotx.core.hardware

import android.content.Context
import android.hardware.Camera
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.os.Build
import javax.inject.Inject

class HardwareInfo @Inject constructor(
private val context: Context
) {
/**
* Tell if the device has a back (or external) camera
*/
fun hasBackCamera(): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return Camera.getNumberOfCameras() > 0
}

val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager? ?: return Camera.getNumberOfCameras() > 0

return manager.cameraIdList.any {
val lensFacing = manager.getCameraCharacteristics(it).get(CameraCharacteristics.LENS_FACING)
lensFacing == CameraCharacteristics.LENS_FACING_BACK || lensFacing == CameraCharacteristics.LENS_FACING_EXTERNAL
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class BadgeFloatingActionButton @JvmOverloads constructor(
attrs?.let { initAttrs(attrs) }
}

@SuppressWarnings("ResourceType", "Recycle")
@SuppressWarnings("Recycle")
private fun initAttrs(attrs: AttributeSet) {
context.obtainStyledAttributes(attrs, R.styleable.BadgeFloatingActionButton).use {
counterBackgroundColor = it.getColor(R.styleable.BadgeFloatingActionButton_badgeBackgroundColor, 0)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotx.features.crypto.verification

import im.vector.matrix.android.api.session.crypto.verification.VerificationMethod
import im.vector.riotx.core.hardware.HardwareInfo
import timber.log.Timber
import javax.inject.Inject

class SupportedVerificationMethodsProvider @Inject constructor(
private val hardwareInfo: HardwareInfo
) {
/**
* Provide the list of supported method by RiotX, with or without the QR_CODE_SCAN, depending if a back camera
* is available
*/
fun provide(): List<VerificationMethod> {
return mutableListOf(
// RiotX supports SAS verification
VerificationMethod.SAS,
// RiotX is able to show QR codes
VerificationMethod.QR_CODE_SHOW)
.apply {
if (hardwareInfo.hasBackCamera()) {
// RiotX is able to scan QR codes, and a Camera is available
add(VerificationMethod.QR_CODE_SCAN)
} else {
// This quite uncommon
Timber.w("No back Camera detected")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,11 @@ data class VerificationBottomSheetViewState(
val isMe: Boolean = false
) : MvRxState

class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted initialState: VerificationBottomSheetViewState,
@Assisted args: VerificationBottomSheet.VerificationArgs,
private val session: Session)
class VerificationBottomSheetViewModel @AssistedInject constructor(
@Assisted initialState: VerificationBottomSheetViewState,
@Assisted args: VerificationBottomSheet.VerificationArgs,
private val session: Session,
private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider)
: VectorViewModel<VerificationBottomSheetViewState, VerificationAction, VerificationBottomSheetViewEvents>(initialState),
VerificationService.Listener {

Expand Down Expand Up @@ -116,9 +118,11 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
if (autoReady) {
// TODO, can I be here in DM mode? in this case should test if roomID is null?
session.cryptoService().verificationService()
.readyPendingVerification(supportedVerificationMethods,
.readyPendingVerification(
supportedVerificationMethodsProvider.provide(),
pr!!.otherUserId,
pr.transactionId ?: "")
pr.transactionId ?: ""
)
}
}

Expand Down Expand Up @@ -173,7 +177,12 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
session
.cryptoService()
.verificationService()
.requestKeyVerificationInDMs(supportedVerificationMethods, otherUserId, data, pendingLocalId)
.requestKeyVerificationInDMs(
supportedVerificationMethodsProvider.provide(),
otherUserId,
data,
pendingLocalId
)
)
)
}
Expand All @@ -191,7 +200,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
pendingRequest = Success(session
.cryptoService()
.verificationService()
.requestKeyVerificationInDMs(supportedVerificationMethods, otherUserId, roomId)
.requestKeyVerificationInDMs(supportedVerificationMethodsProvider.provide(), otherUserId, roomId)
)
)
}
Expand Down Expand Up @@ -294,8 +303,6 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
} catch (failure: Throwable) {
_viewEvents.post(VerificationBottomSheetViewEvents.ModalError(failure.localizedMessage))
}

Unit
}
}.exhaustive
}
Expand Down Expand Up @@ -362,9 +369,11 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
// auto ready in this case, as we are waiting
// TODO, can I be here in DM mode? in this case should test if roomID is null?
session.cryptoService().verificationService()
.readyPendingVerification(supportedVerificationMethods,
.readyPendingVerification(
supportedVerificationMethodsProvider.provide(),
pr.otherUserId,
pr.transactionId ?: "")
pr.transactionId ?: ""
)
}

// Use this one!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import im.vector.riotx.core.resources.UserPreferencesProvider
import im.vector.riotx.core.utils.subscribeLogError
import im.vector.riotx.features.command.CommandParser
import im.vector.riotx.features.command.ParsedCommand
import im.vector.riotx.features.crypto.verification.supportedVerificationMethods
import im.vector.riotx.features.crypto.verification.SupportedVerificationMethodsProvider
import im.vector.riotx.features.home.room.detail.composer.rainbow.RainbowGenerator
import im.vector.riotx.features.home.room.detail.timeline.helper.TimelineDisplayableEvents
import im.vector.riotx.features.home.room.typing.TypingHelper
Expand All @@ -81,13 +81,15 @@ import java.io.File
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean

class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: RoomDetailViewState,
userPreferencesProvider: UserPreferencesProvider,
private val vectorPreferences: VectorPreferences,
private val stringProvider: StringProvider,
private val typingHelper: TypingHelper,
private val rainbowGenerator: RainbowGenerator,
private val session: Session
class RoomDetailViewModel @AssistedInject constructor(
@Assisted initialState: RoomDetailViewState,
userPreferencesProvider: UserPreferencesProvider,
private val vectorPreferences: VectorPreferences,
private val stringProvider: StringProvider,
private val typingHelper: TypingHelper,
private val rainbowGenerator: RainbowGenerator,
private val session: Session,
private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider
) : VectorViewModel<RoomDetailViewState, RoomDetailAction, RoomDetailViewEvents>(initialState), Timeline.Listener {

private val room = session.getRoom(initialState.roomId)!!
Expand Down Expand Up @@ -427,7 +429,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
session
.cryptoService()
.verificationService()
.requestKeyVerificationInDMs(supportedVerificationMethods, slashCommandResult.userId, room.roomId)
.requestKeyVerificationInDMs(supportedVerificationMethodsProvider.provide(), slashCommandResult.userId, room.roomId)
_viewEvents.post(RoomDetailViewEvents.SlashCommandHandled())
popDraft()
}
Expand Down Expand Up @@ -834,7 +836,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) {
Timber.v("## SAS handleAcceptVerification ${action.otherUserId}, roomId:${room.roomId}, txId:${action.transactionId}")
if (session.cryptoService().verificationService().readyPendingVerificationInDMs(
supportedVerificationMethods,
supportedVerificationMethodsProvider.provide(),
action.otherUserId,
room.roomId,
action.transactionId)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ class PollResultLineView @JvmOverloads constructor(
orientation = HORIZONTAL
ButterKnife.bind(this)

val typedArray = context.obtainStyledAttributes(attrs,
R.styleable.PollResultLineView, 0, 0)
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.PollResultLineView, 0, 0)
label = typedArray.getString(R.styleable.PollResultLineView_optionName) ?: ""
percent = typedArray.getString(R.styleable.PollResultLineView_optionCount) ?: ""
optionSelected = typedArray.getBoolean(R.styleable.PollResultLineView_optionSelected, false)
isWinner = typedArray.getBoolean(R.styleable.PollResultLineView_optionIsWinner, false)
typedArray.recycle()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import androidx.core.app.ActivityOptionsCompat
import androidx.core.app.TaskStackBuilder
import androidx.core.view.ViewCompat
import im.vector.matrix.android.api.session.crypto.verification.IncomingSasVerificationTransaction
import im.vector.matrix.android.api.session.crypto.verification.VerificationMethod
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
import im.vector.matrix.android.api.util.MatrixItem
import im.vector.riotx.R
Expand All @@ -35,6 +34,7 @@ import im.vector.riotx.core.utils.toast
import im.vector.riotx.features.createdirect.CreateDirectRoomActivity
import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupManageActivity
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupActivity
import im.vector.riotx.features.crypto.verification.SupportedVerificationMethodsProvider
import im.vector.riotx.features.crypto.verification.VerificationBottomSheet
import im.vector.riotx.features.debug.DebugMenuActivity
import im.vector.riotx.features.home.room.detail.RoomDetailActivity
Expand All @@ -56,7 +56,8 @@ import javax.inject.Singleton
@Singleton
class DefaultNavigator @Inject constructor(
private val sessionHolder: ActiveSessionHolder,
private val vectorPreferences: VectorPreferences
private val vectorPreferences: VectorPreferences,
private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider
) : Navigator {

override fun openRoom(context: Context, roomId: String, eventId: String?, buildTask: Boolean) {
Expand Down Expand Up @@ -85,9 +86,10 @@ class DefaultNavigator @Inject constructor(
override fun requestSessionVerification(context: Context) {
val session = sessionHolder.getSafeActiveSession() ?: return
val pr = session.cryptoService().verificationService().requestKeyVerification(
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
supportedVerificationMethodsProvider.provide(),
session.myUserId,
session.cryptoService().getUserDevices(session.myUserId).map { it.deviceId })
session.cryptoService().getUserDevices(session.myUserId).map { it.deviceId }
)
if (context is VectorBaseActivity) {
VerificationBottomSheet.withArgs(
roomId = null,
Expand Down
Loading