Skip to content

Commit deb01db

Browse files
committed
app passcode m3
Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
1 parent 36dd404 commit deb01db

7 files changed

Lines changed: 273 additions & 73 deletions

File tree

app/src/main/java/com/nextcloud/client/di/ComponentsModule.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
import com.owncloud.android.ui.activity.UploadListActivity;
7979
import com.owncloud.android.ui.activity.UserInfoActivity;
8080
import com.owncloud.android.ui.dialog.AccountRemovalDialog;
81+
import com.owncloud.android.ui.dialog.AppPassCodeDialog;
8182
import com.owncloud.android.ui.dialog.ChooseRichDocumentsTemplateDialogFragment;
8283
import com.owncloud.android.ui.dialog.ChooseTemplateDialogFragment;
8384
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
@@ -427,6 +428,9 @@ abstract class ComponentsModule {
427428
@ContributesAndroidInjector
428429
abstract ThemeSelectionDialog themeSelectionDialog();
429430

431+
@ContributesAndroidInjector
432+
abstract AppPassCodeDialog appPassCodeDialog();
433+
430434
@ContributesAndroidInjector
431435
abstract SharePasswordDialogFragment sharePasswordDialogFragment();
432436

app/src/main/java/com/owncloud/android/ui/activity/ExtendedSettingsActivity.kt

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ class ExtendedSettingsActivity : AppCompatActivity() {
3939
return
4040
}
4141

42-
dialogType.showDialog(this)
42+
val dismissable = intent.getBooleanExtra(EXTRA_DISMISSABLE, true)
43+
dialogType.showDialog(this, dismissable)
4344
dialogShown = true
4445
}
4546

@@ -49,12 +50,18 @@ class ExtendedSettingsActivity : AppCompatActivity() {
4950
}
5051

5152
companion object {
53+
private const val EXTRA_DISMISSABLE = "dismissable"
5254
private const val EXTRA_DIALOG_TYPE = "dialog_type"
5355
private const val KEY_DIALOG_SHOWN = "dialog_shown"
5456

55-
fun createIntent(context: Context, dialogType: ExtendedSettingsActivityDialog): Intent =
56-
Intent(context, ExtendedSettingsActivity::class.java).apply {
57-
putExtra(EXTRA_DIALOG_TYPE, dialogType.key)
58-
}
57+
@JvmOverloads
58+
fun createIntent(
59+
context: Context,
60+
dialogType: ExtendedSettingsActivityDialog,
61+
dismissable: Boolean = true
62+
): Intent = Intent(context, ExtendedSettingsActivity::class.java).apply {
63+
putExtra(EXTRA_DIALOG_TYPE, dialogType.key)
64+
putExtra(EXTRA_DISMISSABLE, dismissable)
65+
}
5966
}
6067
}

app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java

Lines changed: 39 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import android.os.Bundle;
2828
import android.os.Handler;
2929
import android.os.Looper;
30-
import android.preference.ListPreference;
3130
import android.preference.Preference;
3231
import android.preference.PreferenceActivity;
3332
import android.preference.PreferenceCategory;
@@ -65,7 +64,6 @@
6564
import com.owncloud.android.lib.common.ExternalLinkType;
6665
import com.owncloud.android.lib.common.utils.Log_OC;
6766
import com.owncloud.android.providers.DocumentsStorageProvider;
68-
import com.owncloud.android.ui.ListPreferenceDialog;
6967
import com.owncloud.android.ui.ThemeableSwitchPreference;
7068
import com.owncloud.android.ui.asynctasks.LoadingVersionNumberTask;
7169
import com.owncloud.android.ui.dialog.setupEncryption.SetupEncryptionDialogFragment;
@@ -80,7 +78,6 @@
8078
import com.owncloud.android.utils.theme.CapabilityUtils;
8179
import com.owncloud.android.utils.theme.ViewThemeUtils;
8280

83-
import java.util.ArrayList;
8481
import java.util.Objects;
8582

8683
import javax.inject.Inject;
@@ -129,7 +126,7 @@ public class SettingsActivity extends PreferenceActivity
129126

130127
private Uri serverBaseUri;
131128

132-
private ListPreferenceDialog lock;
129+
private Preference lock;
133130
private ThemeableSwitchPreference showHiddenFiles;
134131
private ThemeableSwitchPreference showEcosystemApps;
135132
private AppCompatDelegate delegate;
@@ -212,9 +209,8 @@ public void onBackPressed() {
212209

213210
private void showPasscodeDialogIfEnforceAppProtection() {
214211
if (MDMConfig.INSTANCE.enforceProtection(this) && Objects.equals(preferences.getLockPreference(), SettingsActivity.LOCK_NONE) && lock != null) {
215-
lock.showDialog();
216-
lock.dismissible(false);
217-
lock.enableCancelButton(false);
212+
Intent intent = ExtendedSettingsActivity.Companion.createIntent(this, ExtendedSettingsActivityDialog.AppPasscode, false);
213+
startActivityForResult(intent, ExtendedSettingsActivityDialog.AppPasscode.getResultId());
218214
}
219215
}
220216

@@ -742,63 +738,33 @@ private void setupShowEcosystemAppsPreference(PreferenceCategory preferenceCateg
742738
private void setupLockPreference(PreferenceCategory preferenceCategoryDetails,
743739
boolean passCodeEnabled,
744740
boolean deviceCredentialsEnabled) {
745-
boolean enforceProtection = MDMConfig.INSTANCE.enforceProtection(this);
746-
lock = (ListPreferenceDialog) findPreference(PREFERENCE_LOCK);
747-
int optionSize = 3;
748-
if (enforceProtection) {
749-
optionSize = 2;
750-
}
751-
741+
lock = findPreference(PREFERENCE_LOCK);
752742
if (lock != null && (passCodeEnabled || deviceCredentialsEnabled)) {
753-
ArrayList<String> lockEntries = new ArrayList<>(optionSize);
754-
lockEntries.add(getString(R.string.prefs_lock_using_passcode));
755-
lockEntries.add(getString(R.string.prefs_lock_using_device_credentials));
756-
757-
ArrayList<String> lockValues = new ArrayList<>(optionSize);
758-
lockValues.add(LOCK_PASSCODE);
759-
lockValues.add(LOCK_DEVICE_CREDENTIALS);
760-
761-
if (!enforceProtection) {
762-
lockEntries.add(getString(R.string.prefs_lock_none));
763-
lockValues.add(LOCK_NONE);
764-
}
743+
String currentLock = preferences.getLockPreference();
744+
updateLockSummary(lock, currentLock);
765745

766-
if (!passCodeEnabled) {
767-
lockEntries.remove(getString(R.string.prefs_lock_using_passcode));
768-
lockValues.remove(LOCK_PASSCODE);
769-
} else if (!deviceCredentialsEnabled || !DeviceCredentialUtils.areCredentialsAvailable(getApplicationContext())) {
770-
lockEntries.remove(getString(R.string.prefs_lock_using_device_credentials));
771-
lockValues.remove(LOCK_DEVICE_CREDENTIALS);
772-
}
773-
774-
String[] lockEntriesArr = new String[lockEntries.size()];
775-
lockEntriesArr = lockEntries.toArray(lockEntriesArr);
776-
String[] lockValuesArr = new String[lockValues.size()];
777-
lockValuesArr = lockValues.toArray(lockValuesArr);
778-
779-
lock.setEntries(lockEntriesArr);
780-
lock.setEntryValues(lockValuesArr);
781-
lock.setSummary(lock.getEntry());
782-
783-
lock.setOnPreferenceChangeListener((preference, o) -> {
784-
pendingLock = LOCK_NONE;
785-
String oldValue = ((ListPreference) preference).getValue();
786-
String newValue = (String) o;
787-
if (!oldValue.equals(newValue)) {
788-
if (LOCK_NONE.equals(oldValue)) {
789-
enableLock(newValue);
790-
} else {
791-
pendingLock = newValue;
792-
disableLock(oldValue);
793-
}
794-
}
795-
return false;
746+
lock.setOnPreferenceClickListener(preference -> {
747+
Intent intent = ExtendedSettingsActivity.Companion.createIntent(this, ExtendedSettingsActivityDialog.AppPasscode);
748+
startActivityForResult(intent, ExtendedSettingsActivityDialog.AppPasscode.getResultId());
749+
return true;
796750
});
797751
} else {
798752
preferenceCategoryDetails.removePreference(lock);
799753
}
800754
}
801755

756+
private void updateLockSummary(Preference lockPreference, String lockValue) {
757+
String summary;
758+
if (LOCK_PASSCODE.equals(lockValue)) {
759+
summary = getString(R.string.prefs_lock_using_passcode);
760+
} else if (LOCK_DEVICE_CREDENTIALS.equals(lockValue)) {
761+
summary = getString(R.string.prefs_lock_using_device_credentials);
762+
} else {
763+
summary = getString(R.string.prefs_lock_none);
764+
}
765+
lockPreference.setSummary(summary);
766+
}
767+
802768
private void setupAutoUploadCategory(PreferenceScreen preferenceScreen) {
803769
final PreferenceCategory preferenceCategorySyncedFolders =
804770
(PreferenceCategory) findPreference("synced_folders_category");
@@ -853,8 +819,10 @@ private void enableLock(String lock) {
853819
}
854820

855821
private void changeLockSetting(String value) {
856-
lock.setValue(value);
857-
lock.setSummary(lock.getEntry());
822+
preferences.setLockPreference(value);
823+
if (lock != null) {
824+
updateLockSummary(lock, value);
825+
}
858826
DocumentsStorageProvider.notifyRootsChanged(this);
859827
}
860828

@@ -1067,6 +1035,19 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
10671035
// needed for to change status bar color
10681036
recreate();
10691037
}
1038+
} else if (requestCode == ExtendedSettingsActivityDialog.AppPasscode.getResultId() && data != null) {
1039+
String selectedLock = data.getStringExtra(ExtendedSettingsActivityDialog.AppPasscode.getKey());
1040+
if (selectedLock != null) {
1041+
String currentLock = preferences.getLockPreference();
1042+
if (!currentLock.equals(selectedLock)) {
1043+
if (LOCK_NONE.equals(currentLock)) {
1044+
enableLock(selectedLock);
1045+
} else {
1046+
pendingLock = selectedLock;
1047+
disableLock(currentLock);
1048+
}
1049+
}
1050+
}
10701051
} else if (requestCode == REQ_ALL_FILES_ACCESS) {
10711052
final PreferenceCategory preferenceCategorySync = (PreferenceCategory) findPreference("sync");
10721053
setupAllFilesAccessPreference(preferenceCategorySync);
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
package com.owncloud.android.ui.dialog
9+
10+
import android.app.Dialog
11+
import android.os.Bundle
12+
import androidx.appcompat.app.AlertDialog
13+
import androidx.core.os.bundleOf
14+
import androidx.fragment.app.DialogFragment
15+
import androidx.fragment.app.setFragmentResult
16+
import com.google.android.material.button.MaterialButton
17+
import com.google.android.material.dialog.MaterialAlertDialogBuilder
18+
import com.nextcloud.client.di.Injectable
19+
import com.nextcloud.client.preferences.AppPreferences
20+
import com.nextcloud.utils.extensions.setVisibleIf
21+
import com.nextcloud.utils.mdm.MDMConfig
22+
import com.owncloud.android.R
23+
import com.owncloud.android.databinding.DialogAppPasscodeBinding
24+
import com.owncloud.android.ui.activity.SettingsActivity
25+
import com.owncloud.android.ui.model.ExtendedSettingsActivityDialog
26+
import com.owncloud.android.utils.DeviceCredentialUtils
27+
import com.owncloud.android.utils.theme.ViewThemeUtils
28+
import javax.inject.Inject
29+
30+
class AppPassCodeDialog :
31+
DialogFragment(),
32+
Injectable {
33+
34+
@Inject
35+
lateinit var preferences: AppPreferences
36+
37+
@Inject
38+
lateinit var viewThemeUtils: ViewThemeUtils
39+
40+
private lateinit var binding: DialogAppPasscodeBinding
41+
42+
override fun onStart() {
43+
super.onStart()
44+
val alertDialog = dialog as AlertDialog
45+
46+
val positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE) as? MaterialButton
47+
positiveButton?.let {
48+
viewThemeUtils.material.colorMaterialButtonPrimaryTonal(it)
49+
}
50+
51+
val dismissable = arguments?.getBoolean(ARG_DISMISSABLE, true) ?: true
52+
isCancelable = dismissable
53+
}
54+
55+
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
56+
binding = DialogAppPasscodeBinding.inflate(layoutInflater)
57+
58+
val currentLock = preferences.lockPreference ?: SettingsActivity.LOCK_NONE
59+
val passCodeEnabled = resources.getBoolean(R.bool.passcode_enabled)
60+
val deviceCredentialsEnabled = resources.getBoolean(R.bool.device_credentials_enabled)
61+
val enforceProtection = MDMConfig.enforceProtection(requireContext())
62+
val deviceCredentialsAvailable = DeviceCredentialUtils.areCredentialsAvailable(requireContext())
63+
val dismissable = arguments?.getBoolean(ARG_DISMISSABLE, true) ?: true
64+
65+
binding.lockPasscode.setVisibleIf(passCodeEnabled)
66+
binding.lockDeviceCredentials.setVisibleIf(deviceCredentialsEnabled && deviceCredentialsAvailable)
67+
binding.lockNone.setVisibleIf(!enforceProtection)
68+
69+
setupTheme()
70+
setCurrentSelection(currentLock)
71+
setupListener()
72+
73+
val builder = MaterialAlertDialogBuilder(requireContext())
74+
.setView(binding.root)
75+
.setPositiveButton(R.string.common_ok) { _, _ ->
76+
applySelection()
77+
dismiss()
78+
}
79+
80+
if (!enforceProtection && dismissable) {
81+
builder.setNegativeButton(R.string.common_cancel) { _, _ ->
82+
dismiss()
83+
}
84+
}
85+
86+
builder.setCancelable(dismissable)
87+
88+
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(requireContext(), builder)
89+
90+
return builder.create()
91+
}
92+
93+
private fun setupTheme() {
94+
viewThemeUtils.platform.apply {
95+
colorTextView(binding.dialogTitle)
96+
themeRadioButton(binding.lockPasscode)
97+
themeRadioButton(binding.lockDeviceCredentials)
98+
themeRadioButton(binding.lockNone)
99+
}
100+
}
101+
102+
private fun setCurrentSelection(currentLock: String) {
103+
val radioGroup = binding.lockRadioGroup
104+
105+
when (currentLock) {
106+
SettingsActivity.LOCK_PASSCODE -> radioGroup.check(R.id.lock_passcode)
107+
SettingsActivity.LOCK_DEVICE_CREDENTIALS -> radioGroup.check(R.id.lock_device_credentials)
108+
SettingsActivity.LOCK_NONE -> radioGroup.check(R.id.lock_none)
109+
}
110+
}
111+
112+
private fun setupListener() {
113+
binding.lockRadioGroup.setOnCheckedChangeListener { _, checkedId ->
114+
val selectedLock = when (checkedId) {
115+
R.id.lock_passcode -> SettingsActivity.LOCK_PASSCODE
116+
R.id.lock_device_credentials -> SettingsActivity.LOCK_DEVICE_CREDENTIALS
117+
R.id.lock_none -> SettingsActivity.LOCK_NONE
118+
else -> SettingsActivity.LOCK_NONE
119+
}
120+
121+
currentSelection = selectedLock
122+
}
123+
}
124+
125+
private var currentSelection: String? = null
126+
127+
private fun applySelection() {
128+
val selectedLock = currentSelection ?: return
129+
130+
setFragmentResult(
131+
ExtendedSettingsActivityDialog.AppPasscode.key,
132+
bundleOf(ExtendedSettingsActivityDialog.AppPasscode.key to selectedLock)
133+
)
134+
}
135+
136+
companion object {
137+
private const val ARG_DISMISSABLE = "dismissable"
138+
139+
fun instance(dismissable: Boolean): AppPassCodeDialog = AppPassCodeDialog().apply {
140+
arguments = bundleOf(ARG_DISMISSABLE to dismissable)
141+
}
142+
}
143+
}

app/src/main/java/com/owncloud/android/ui/model/ExtendedSettingsActivityDialog.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ import android.app.Activity.RESULT_OK
1111
import android.content.Intent
1212
import com.nextcloud.ui.ChooseStorageLocationDialogFragment
1313
import com.owncloud.android.ui.activity.ExtendedSettingsActivity
14+
import com.owncloud.android.ui.dialog.AppPassCodeDialog
1415
import com.owncloud.android.ui.dialog.ThemeSelectionDialog
1516

1617
@Suppress("MagicNumber")
1718
enum class ExtendedSettingsActivityDialog(val tag: String, val key: String, val resultId: Int) {
1819
StorageLocation("choose_storage_location", "storage_selection_result", 13),
19-
ThemeSelection("theme_selection", "theme_selection_result", 14);
20+
ThemeSelection("theme_selection", "theme_selection_result", 14),
21+
AppPasscode("app_passcode", "app_passcode_result", 15);
2022

21-
fun showDialog(activity: ExtendedSettingsActivity) {
23+
fun showDialog(activity: ExtendedSettingsActivity, dismissable: Boolean = true) {
2224
activity.run {
2325
if (supportFragmentManager.findFragmentByTag(tag) != null) {
2426
return
@@ -38,13 +40,11 @@ enum class ExtendedSettingsActivityDialog(val tag: String, val key: String, val
3840
finish()
3941
}
4042

41-
if (this@ExtendedSettingsActivityDialog == StorageLocation) {
42-
ChooseStorageLocationDialogFragment()
43-
} else {
44-
ThemeSelectionDialog()
45-
}.run {
46-
show(supportFragmentManager, tag)
47-
}
43+
when (this@ExtendedSettingsActivityDialog) {
44+
StorageLocation -> ChooseStorageLocationDialogFragment()
45+
ThemeSelection -> ThemeSelectionDialog()
46+
AppPasscode -> AppPassCodeDialog.instance(dismissable)
47+
}.show(supportFragmentManager, tag)
4848
}
4949
}
5050
}

0 commit comments

Comments
 (0)