Skip to content
Open
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
6 changes: 6 additions & 0 deletions changelog/unreleased/4871
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Passcode and pattern screens in landscape mode

Orientation restrictions defined in the manifest have been removed, and support for both
orientations (portrait and landscape) has been added to the passcode and pattern screens.

https://github.com/owncloud/android/pull/4871
2 changes: 0 additions & 2 deletions owncloudApp/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@
<activity
android:name=".presentation.security.passcode.PassCodeActivity"
android:label="@string/passcode_label"
android:screenOrientation="portrait"
android:theme="@style/Theme.ownCloud" />
<activity
android:name=".presentation.conflicts.ConflictsResolveActivity"
Expand Down Expand Up @@ -235,7 +234,6 @@
android:theme="@style/Theme.ownCloud.Toolbar"/>
<activity
android:name=".presentation.security.pattern.PatternActivity"
android:screenOrientation="portrait"
android:label="@string/pattern_label"
android:theme="@style/Theme.ownCloud" />
<activity android:name=".presentation.security.biometric.BiometricActivity" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* @author Jorge Aguado Recio
*
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2025 ownCloud GmbH.
* Copyright (C) 2026 ownCloud GmbH.
* <p>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
Expand Down Expand Up @@ -42,7 +42,7 @@ import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import com.owncloud.android.BuildConfig
import com.owncloud.android.R
import com.owncloud.android.databinding.PasscodelockBinding
import com.owncloud.android.databinding.PasscodeLockActivityBinding
import com.owncloud.android.domain.utils.Event
import com.owncloud.android.extensions.showBiometricDialog
import com.owncloud.android.extensions.showMessageInSnackbar
Expand All @@ -66,7 +66,7 @@ class PassCodeActivity : AppCompatActivity(), NumberKeyboardListener, EnableBiom

private val biometricViewModel by viewModel<BiometricViewModel>()

private var _binding: PasscodelockBinding? = null
private var _binding: PasscodeLockActivityBinding? = null
val binding get() = _binding!!

private lateinit var passCodeEditTexts: Array<EditText?>
Expand All @@ -87,7 +87,7 @@ class PassCodeActivity : AppCompatActivity(), NumberKeyboardListener, EnableBiom

subscribeToViewModel()

_binding = PasscodelockBinding.inflate(layoutInflater)
_binding = PasscodeLockActivityBinding.inflate(layoutInflater)

// protection against screen recording
if (!BuildConfig.DEBUG) {
Expand All @@ -106,7 +106,7 @@ class PassCodeActivity : AppCompatActivity(), NumberKeyboardListener, EnableBiom
// Allow or disallow touches with other visible windows
binding.passcodeLockLayout.filterTouchesWhenObscured =
PreferenceUtils.shouldDisallowTouchesWithOtherVisibleWindows(this)
binding.explanation.filterTouchesWhenObscured =
binding.passcodeExplanation.filterTouchesWhenObscured =
PreferenceUtils.shouldDisallowTouchesWithOtherVisibleWindows(this)

inflatePasscodeTxtLine()
Expand All @@ -120,8 +120,8 @@ class PassCodeActivity : AppCompatActivity(), NumberKeyboardListener, EnableBiom
when (intent.action) {
ACTION_CHECK -> { //When you start the app with passcode
// this is a pass code request; the user has to input the right value
binding.header.text = getString(R.string.pass_code_enter_pass_code)
binding.explanation.visibility = View.INVISIBLE
binding.passcodeHeader.text = getString(R.string.pass_code_enter_pass_code)
binding.passcodeExplanation.visibility = View.INVISIBLE
supportActionBar?.setDisplayHomeAsUpEnabled(false) //Don´t show the back arrow
}

Expand All @@ -131,14 +131,14 @@ class PassCodeActivity : AppCompatActivity(), NumberKeyboardListener, EnableBiom
requestPassCodeConfirmation()
} else {
if (intent.extras?.getBoolean(EXTRAS_MIGRATION) == true) {
binding.header.text =
binding.passcodeHeader.text =
getString(R.string.pass_code_configure_your_pass_code_migration, passCodeViewModel.getNumberOfPassCodeDigits())
} else {
// pass code preference has just been activated in Preferences;
// will receive and confirm pass code value
binding.header.text = getString(R.string.pass_code_configure_your_pass_code)
binding.passcodeHeader.text = getString(R.string.pass_code_configure_your_pass_code)
}
binding.explanation.visibility = View.VISIBLE
binding.passcodeExplanation.visibility = View.VISIBLE
when {
intent.extras?.getBoolean(EXTRAS_MIGRATION) == true -> {
supportActionBar?.setDisplayHomeAsUpEnabled(false)
Expand All @@ -158,8 +158,8 @@ class PassCodeActivity : AppCompatActivity(), NumberKeyboardListener, EnableBiom
ACTION_REMOVE -> { // Remove password
// pass code preference has just been disabled in Preferences;
// will confirm user knows pass code, then remove it
binding.header.text = getString(R.string.pass_code_remove_your_pass_code)
binding.explanation.visibility = View.INVISIBLE
binding.passcodeHeader.text = getString(R.string.pass_code_remove_your_pass_code)
binding.passcodeExplanation.visibility = View.INVISIBLE
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}

Expand All @@ -180,7 +180,7 @@ class PassCodeActivity : AppCompatActivity(), NumberKeyboardListener, EnableBiom
}

private fun inflatePasscodeTxtLine() {
val layoutCode = findViewById<LinearLayout>(R.id.layout_code)
val layoutCode = findViewById<LinearLayout>(R.id.passcode_value)
val numberOfPasscodeDigits = (passCodeViewModel.getPassCode()?.length ?: passCodeViewModel.getNumberOfPassCodeDigits())
for (i in 0 until numberOfPasscodeDigits) {
val txt = layoutInflater.inflate(R.layout.passcode_edit_text, layoutCode, false) as EditText
Expand Down Expand Up @@ -259,14 +259,14 @@ class PassCodeActivity : AppCompatActivity(), NumberKeyboardListener, EnableBiom

private fun actionCheckOk() {
// pass code accepted in request, user is allowed to access the app
binding.error.visibility = View.INVISIBLE
binding.passcodeError.visibility = View.INVISIBLE

PassCodeManager.onActivityStopped(this)
finish()
}

private fun actionCheckMigration() {
binding.error.visibility = View.INVISIBLE
binding.passcodeError.visibility = View.INVISIBLE

val intent = Intent(baseContext, PassCodeActivity::class.java)
intent.apply {
Expand Down Expand Up @@ -305,7 +305,7 @@ class PassCodeActivity : AppCompatActivity(), NumberKeyboardListener, EnableBiom
}

private fun actionCreateNoConfirm() {
binding.error.visibility = View.INVISIBLE
binding.passcodeError.visibility = View.INVISIBLE
requestPassCodeConfirmation()
}

Expand Down Expand Up @@ -341,10 +341,10 @@ class PassCodeActivity : AppCompatActivity(), NumberKeyboardListener, EnableBiom
errorMessage: Int, headerMessage: String,
explanationVisibility: Int
) {
binding.error.setText(errorMessage)
binding.error.visibility = View.VISIBLE
binding.header.text = headerMessage
binding.explanation.visibility = explanationVisibility
binding.passcodeError.setText(errorMessage)
binding.passcodeError.visibility = View.VISIBLE
binding.passcodeHeader.text = headerMessage
binding.passcodeExplanation.visibility = explanationVisibility
clearBoxes()
}

Expand All @@ -354,8 +354,8 @@ class PassCodeActivity : AppCompatActivity(), NumberKeyboardListener, EnableBiom
*/
private fun requestPassCodeConfirmation() {
clearBoxes()
binding.header.setText(R.string.pass_code_reenter_your_pass_code)
binding.explanation.visibility = View.INVISIBLE
binding.passcodeHeader.setText(R.string.pass_code_reenter_your_pass_code)
binding.passcodeExplanation.visibility = View.INVISIBLE
confirmingPassCode = true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* @author Juan Carlos Garrote Gascón
* @author Jorge Aguado Recio
*
* Copyright (C) 2025 ownCloud GmbH.
* Copyright (C) 2026 ownCloud GmbH.
* <p>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
Expand Down Expand Up @@ -40,7 +40,7 @@ import com.andrognito.patternlockview.utils.PatternLockUtils
import com.owncloud.android.BuildConfig
import com.owncloud.android.R
import com.owncloud.android.data.providers.implementation.OCSharedPreferencesProvider
import com.owncloud.android.databinding.ActivityPatternLockBinding
import com.owncloud.android.databinding.PatternLockActivityBinding
import com.owncloud.android.extensions.showBiometricDialog
import com.owncloud.android.extensions.showMessageInSnackbar
import com.owncloud.android.presentation.documentsprovider.DocumentsProviderUtils.notifyDocumentsProviderRoots
Expand All @@ -59,7 +59,7 @@ class PatternActivity : AppCompatActivity(), EnableBiometrics {
private val patternViewModel by viewModel<PatternViewModel>()
private val biometricViewModel by viewModel<BiometricViewModel>()

private var _binding: ActivityPatternLockBinding? = null
private var _binding: PatternLockActivityBinding? = null
val binding get() = _binding!!

private var confirmingPattern = false
Expand All @@ -75,7 +75,7 @@ class PatternActivity : AppCompatActivity(), EnableBiometrics {
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
}

_binding = ActivityPatternLockBinding.inflate(layoutInflater)
_binding = PatternLockActivityBinding.inflate(layoutInflater)

setContentView(binding.root)

Expand All @@ -102,8 +102,8 @@ class PatternActivity : AppCompatActivity(), EnableBiometrics {
* This block is executed when the user opens the app after setting the pattern lock
* this block takes the pattern input by the user and checks it with the pattern initially set by the user.
*/
binding.headerPattern.text = getString(R.string.pattern_enter_pattern)
binding.explanationPattern.visibility = View.INVISIBLE
binding.patternHeader.text = getString(R.string.pattern_enter_pattern)
binding.patternExplanation.visibility = View.INVISIBLE
supportActionBar?.setDisplayHomeAsUpEnabled(false)
}
ACTION_REQUEST_WITH_RESULT -> {
Expand All @@ -118,13 +118,13 @@ class PatternActivity : AppCompatActivity(), EnableBiometrics {
patternExpShouldVisible = savedInstanceState.getBoolean(PATTERN_EXP_VIEW_STATE)
}
if (confirmingPattern) {
binding.headerPattern.text = headerPatternViewText
binding.patternHeader.text = headerPatternViewText
if (!patternExpShouldVisible) {
binding.explanationPattern.visibility = View.INVISIBLE
binding.patternExplanation.visibility = View.INVISIBLE
}
} else {
binding.headerPattern.text = getString(R.string.pattern_configure_pattern)
binding.explanationPattern.visibility = View.VISIBLE
binding.patternHeader.text = getString(R.string.pattern_configure_pattern)
binding.patternExplanation.visibility = View.VISIBLE
if (intent.extras?.getBoolean(EXTRAS_LOCK_ENFORCED) == true) {
supportActionBar?.setDisplayHomeAsUpEnabled(false)
} else {
Expand All @@ -136,9 +136,9 @@ class PatternActivity : AppCompatActivity(), EnableBiometrics {
/**
* This block is executed when the user is removing the pattern lock (i.e disabling the pattern lock)
*/
binding.headerPattern.text = getString(R.string.pattern_remove_pattern)
binding.explanationPattern.text = getString(R.string.pattern_no_longer_required)
binding.explanationPattern.visibility = View.VISIBLE
binding.patternHeader.text = getString(R.string.pattern_remove_pattern)
binding.patternExplanation.text = getString(R.string.pattern_no_longer_required)
binding.patternExplanation.visibility = View.VISIBLE
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
else -> {
Expand Down Expand Up @@ -223,7 +223,7 @@ class PatternActivity : AppCompatActivity(), EnableBiometrics {

private fun handleActionCheck() {
if (patternViewModel.checkPatternIsValid(patternValue)) {
binding.errorPattern.visibility = View.INVISIBLE
binding.patternError.visibility = View.INVISIBLE
val preferencesProvider = OCSharedPreferencesProvider(applicationContext)
preferencesProvider.putLong(PREFERENCE_LAST_UNLOCK_TIMESTAMP, SystemClock.elapsedRealtime())
PatternManager.onActivityStopped(this)
Expand All @@ -241,7 +241,7 @@ class PatternActivity : AppCompatActivity(), EnableBiometrics {
patternViewModel.removePattern()
val result = Intent()
setResult(RESULT_OK, result)
binding.errorPattern.visibility = View.INVISIBLE
binding.patternError.visibility = View.INVISIBLE
notifyDocumentsProviderRoots(applicationContext)
finish()
} else {
Expand All @@ -254,7 +254,7 @@ class PatternActivity : AppCompatActivity(), EnableBiometrics {

private fun handleActionRequestWithResult() {
if (!confirmingPattern) {
binding.errorPattern.visibility = View.INVISIBLE
binding.patternError.visibility = View.INVISIBLE
requestPatternConfirmation()
} else if (confirmPattern()) {
savePatternAndExit()
Expand All @@ -271,19 +271,19 @@ class PatternActivity : AppCompatActivity(), EnableBiometrics {
explanationVisibility: Int
) {
patternValue = null
binding.errorPattern.setText(errorMessage)
binding.errorPattern.visibility = View.VISIBLE
binding.headerPattern.setText(headerMessage)
binding.explanationPattern.visibility = explanationVisibility
binding.patternError.setText(errorMessage)
binding.patternError.visibility = View.VISIBLE
binding.patternHeader.setText(headerMessage)
binding.patternExplanation.visibility = explanationVisibility
}

/**
* Ask to the user to re-enter the pattern just entered before saving it as the current pattern.
*/
private fun requestPatternConfirmation() {
binding.patternLockView.clearPattern()
binding.headerPattern.setText(R.string.pattern_reenter_pattern)
binding.explanationPattern.visibility = View.INVISIBLE
binding.patternHeader.setText(R.string.pattern_reenter_pattern)
binding.patternExplanation.visibility = View.INVISIBLE
confirmingPattern = true
}

Expand All @@ -309,8 +309,8 @@ class PatternActivity : AppCompatActivity(), EnableBiometrics {
outState.apply {
putBoolean(KEY_CONFIRMING_PATTERN, confirmingPattern)
putString(KEY_PATTERN_STRING, patternValue)
putString(PATTERN_HEADER_VIEW_TEXT, binding.headerPattern.text.toString())
putBoolean(PATTERN_EXP_VIEW_STATE, binding.explanationPattern.isVisible)
putString(PATTERN_HEADER_VIEW_TEXT, binding.patternHeader.text.toString())
putBoolean(PATTERN_EXP_VIEW_STATE, binding.patternExplanation.isVisible)
}
}

Expand Down
Loading
Loading