From 79b98a48c2692a869ddb503e70d6584017034faa Mon Sep 17 00:00:00 2001 From: "daniel.boehrs" Date: Mon, 1 Oct 2018 09:12:05 +0200 Subject: [PATCH] App screen lock #42 --- res/values/strings.xml | 7 +- res/xml/preferences_app_protection.xml | 71 ++-- .../securesms/ApplicationContext.java | 8 +- .../securesms/BaseActionBarActivity.java | 54 ++- .../AppProtectionPreferenceFragment.java | 309 ++++++------------ .../securesms/service/KeyCachingService.java | 2 +- .../securesms/util/ScreenLockUtil.java | 54 +++ .../securesms/util/TextSecurePreferences.java | 10 +- 8 files changed, 249 insertions(+), 266 deletions(-) create mode 100644 src/org/thoughtcrime/securesms/util/ScreenLockUtil.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 1a3d5d791b..1d236c1c69 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1063,15 +1063,15 @@ Pressing the Enter key will send text messages Choose identity Choose your contact entry from the contacts list. - Change passphrase - Change your passphrase + Change secret + Change your pin / pattern / fingerprint via system settings Enable passphrase screen lock Lock screen and notifications with a passphrase Screen security To apply the screen security setting please restart the app Block screenshots in the recents list and inside the app Auto-lock Delta Chat after a specified time interval of inactivity - Inactivity timeout passphrase + Inactivity timeout lock Inactivity timeout interval Notifications LED color @@ -1473,5 +1473,6 @@ Type email address above New chat https://delta.chat/en/help + Authentication failed. diff --git a/res/xml/preferences_app_protection.xml b/res/xml/preferences_app_protection.xml index 136429a8d8..53c4aa2500 100644 --- a/res/xml/preferences_app_protection.xml +++ b/res/xml/preferences_app_protection.xml @@ -4,62 +4,55 @@ - - - - + android:defaultValue="false" + android:key="pref_android_screen_lock" + android:summary="@string/preferences_app_protection__lock_signal_access_with_android_screen_lock_or_fingerprint" + android:title="@string/preferences_app_protection__screen_lock" /> - + + android:defaultValue="false" + android:key="pref_timeout_passphrase" + android:summary="@string/preferences__auto_lock_signal_after_a_specified_time_interval_of_inactivity" + android:title="@string/preferences__inactivity_timeout_passphrase" /> - + + android:defaultValue="false" + android:key="pref_screen_security" + android:summary="@string/preferences__disable_screen_security_to_allow_screen_shots" + android:title="@string/preferences__screen_security" /> + android:summary="@string/preferences__request_keyboard_to_disable_personalized_learning" + android:title="@string/preferences__incognito_keyboard" /> + - + + android:defaultValue="false" + android:key="pref_read_receipts" + android:summary="@string/preferences__if_read_receipts_are_disabled_you_wont_be_able_to_see_read_receipts" + android:title="@string/preferences__read_receipts" /> + + - diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index 523b24b866..00dcb0f127 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -16,19 +16,15 @@ */ package org.thoughtcrime.securesms; -import android.annotation.SuppressLint; import android.arch.lifecycle.DefaultLifecycleObserver; import android.arch.lifecycle.LifecycleOwner; import android.arch.lifecycle.ProcessLifecycleOwner; import android.content.Context; -import android.os.AsyncTask; import android.os.Build; import android.support.annotation.NonNull; import android.support.multidex.MultiDexApplication; import android.util.Log; -import com.google.android.gms.security.ProviderInstaller; - import org.thoughtcrime.securesms.connect.ApplicationDcContext; import org.thoughtcrime.securesms.crypto.PRNGFixes; import org.thoughtcrime.securesms.dependencies.AxolotlStorageModule; @@ -45,6 +41,7 @@ import org.thoughtcrime.securesms.jobs.requirements.SqlCipherMigrationRequirementProvider; import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess; import org.thoughtcrime.securesms.service.ExpiringMessageManager; +import org.thoughtcrime.securesms.util.ScreenLockUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.webrtc.PeerConnectionFactory; import org.webrtc.PeerConnectionFactory.InitializationOptions; @@ -55,7 +52,6 @@ import java.util.HashSet; import java.util.Set; -import java.util.concurrent.TimeUnit; import dagger.ObjectGraph; @@ -105,7 +101,6 @@ public void onCreate() { public void onStart(@NonNull LifecycleOwner owner) { isAppVisible = true; Log.i(TAG, "App is now visible."); - executePendingContactSync(); } @@ -113,6 +108,7 @@ public void onStart(@NonNull LifecycleOwner owner) { public void onStop(@NonNull LifecycleOwner owner) { isAppVisible = false; Log.i(TAG, "App is no longer visible."); + ScreenLockUtil.shouldLockApp = true; } @Override diff --git a/src/org/thoughtcrime/securesms/BaseActionBarActivity.java b/src/org/thoughtcrime/securesms/BaseActionBarActivity.java index 2a410fef4d..e6d96a607f 100644 --- a/src/org/thoughtcrime/securesms/BaseActionBarActivity.java +++ b/src/org/thoughtcrime/securesms/BaseActionBarActivity.java @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms; import android.annotation.TargetApi; -import android.app.ActivityOptions; import android.content.Intent; import android.os.Build; import android.os.Build.VERSION_CODES; @@ -15,16 +14,23 @@ import android.view.View; import android.view.ViewConfiguration; import android.view.WindowManager; -import android.view.animation.AnimationUtils; +import android.widget.Toast; +import org.thoughtcrime.securesms.util.ScreenLockUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.lang.reflect.Field; +import java.util.Timer; + +import static org.thoughtcrime.securesms.util.ScreenLockUtil.shouldLockApp; public abstract class BaseActionBarActivity extends AppCompatActivity { + private static final String TAG = BaseActionBarActivity.class.getSimpleName(); + private Timer timer; + @Override protected void onCreate(Bundle savedInstanceState) { if (BaseActivity.isMenuWorkaroundRequired()) { @@ -33,10 +39,54 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } + @Override + protected void onStart() { + super.onStart(); + if (ScreenLockUtil.isScreenLockEnabled(this) && shouldLockApp) { + ScreenLockUtil.applyScreenLock(this); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == ScreenLockUtil.REQUEST_CODE_CONFIRM_CREDENTIALS) { + if (resultCode == RESULT_OK) { + shouldLockApp = false; + } else { + Toast.makeText(this, R.string.security_authentication_failed, Toast.LENGTH_SHORT).show(); + } + } + } + @Override protected void onResume() { super.onResume(); initializeScreenshotSecurity(); + initializeScreenLock(); + } + + private void initializeScreenLock() { + if (ScreenLockUtil.isScreenLockEnabled(this)) { + timer = ScreenLockUtil.scheduleScreenLockTimer(timer, this); + } + } + + @Override + protected void onPause() { + super.onPause(); + tearDownScreenLock(); + } + + private void tearDownScreenLock() { + if (ScreenLockUtil.isScreenLockEnabled(this)) { + ScreenLockUtil.cancelScreenLockTimer(timer); + } + } + + @Override + public void onUserInteraction() { + super.onUserInteraction(); + initializeScreenLock(); } @Override diff --git a/src/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java b/src/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java index 946e38d9f5..bb8873ce1b 100644 --- a/src/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java +++ b/src/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java @@ -4,25 +4,19 @@ import android.app.KeyguardManager; import android.content.Context; import android.content.Intent; -import android.os.Build; import android.os.Bundle; +import android.provider.Settings; import android.support.annotation.Nullable; -import android.support.v7.app.AlertDialog; -import android.support.v7.preference.CheckBoxPreference; import android.support.v7.preference.Preference; import android.widget.Toast; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.ApplicationPreferencesActivity; import org.thoughtcrime.securesms.BlockedContactsActivity; -import org.thoughtcrime.securesms.PassphraseChangeActivity; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.components.SwitchPreferenceCompat; -import org.thoughtcrime.securesms.crypto.MasterSecretUtil; import org.thoughtcrime.securesms.dependencies.InjectableType; import org.thoughtcrime.securesms.jobs.MultiDeviceReadReceiptUpdateJob; -import org.thoughtcrime.securesms.lock.RegistrationLockDialog; -import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.SignalServiceAccountManager; @@ -34,243 +28,138 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment implements InjectableType { - private static final String PREFERENCE_CATEGORY_BLOCKED = "preference_category_blocked"; + private static final String PREFERENCE_CATEGORY_BLOCKED = "preference_category_blocked"; - private CheckBoxPreference disablePassphrase; + @Inject + SignalServiceAccountManager accountManager; - @Inject - SignalServiceAccountManager accountManager; - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - ApplicationContext.getInstance(activity).injectDependencies(this); - } - - @Override - public void onCreate(Bundle paramBundle) { - super.onCreate(paramBundle); - - disablePassphrase = (CheckBoxPreference) this.findPreference("pref_enable_passphrase_temporary"); - - this.findPreference(TextSecurePreferences.SCREEN_LOCK).setOnPreferenceChangeListener(new ScreenLockListener()); - this.findPreference(TextSecurePreferences.SCREEN_LOCK_TIMEOUT).setOnPreferenceClickListener(new ScreenLockTimeoutListener()); - this.findPreference(TextSecurePreferences.SCREEN_SECURITY_PREF).setOnPreferenceChangeListener(new ScreenSecurityListener()); - - this.findPreference(TextSecurePreferences.CHANGE_PASSPHRASE_PREF).setOnPreferenceClickListener(new ChangePassphraseClickListener()); - this.findPreference(TextSecurePreferences.PASSPHRASE_TIMEOUT_INTERVAL_PREF).setOnPreferenceClickListener(new PassphraseIntervalClickListener()); - this.findPreference(TextSecurePreferences.READ_RECEIPTS_PREF).setOnPreferenceChangeListener(new ReadReceiptToggleListener()); - this.findPreference(PREFERENCE_CATEGORY_BLOCKED).setOnPreferenceClickListener(new BlockedContactsClickListener()); - disablePassphrase.setOnPreferenceChangeListener(new DisablePassphraseClickListener()); - - initializeVisibility(); - } - - @Override - public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { - addPreferencesFromResource(R.xml.preferences_app_protection); - } - - @Override - public void onResume() { - super.onResume(); - ((ApplicationPreferencesActivity) getActivity()).getSupportActionBar().setTitle(R.string.preferences__privacy); - - if (!TextSecurePreferences.isPasswordDisabled(getContext())) initializePassphraseTimeoutSummary(); - else initializeScreenLockTimeoutSummary(); - - disablePassphrase.setChecked(!TextSecurePreferences.isPasswordDisabled(getActivity())); - } - - private void initializePassphraseTimeoutSummary() { - int timeoutMinutes = TextSecurePreferences.getPassphraseTimeoutInterval(getActivity()); - this.findPreference(TextSecurePreferences.PASSPHRASE_TIMEOUT_INTERVAL_PREF) - .setSummary(getResources().getQuantityString(R.plurals.AppProtectionPreferenceFragment_minutes, timeoutMinutes, timeoutMinutes)); - } - - private void initializeScreenLockTimeoutSummary() { - long timeoutSeconds = TextSecurePreferences.getScreenLockTimeout(getContext()); - long hours = TimeUnit.SECONDS.toHours(timeoutSeconds); - long minutes = TimeUnit.SECONDS.toMinutes(timeoutSeconds) - (TimeUnit.SECONDS.toHours(timeoutSeconds) * 60 ); - long seconds = TimeUnit.SECONDS.toSeconds(timeoutSeconds) - (TimeUnit.SECONDS.toMinutes(timeoutSeconds) * 60); - - findPreference(TextSecurePreferences.SCREEN_LOCK_TIMEOUT) - .setSummary(timeoutSeconds <= 0 ? getString(R.string.AppProtectionPreferenceFragment_none) : - String.format("%02d:%02d:%02d", hours, minutes, seconds)); - } - - private void initializeVisibility() { - if (TextSecurePreferences.isPasswordDisabled(getContext())) { - findPreference("pref_enable_passphrase_temporary").setVisible(false); - findPreference(TextSecurePreferences.CHANGE_PASSPHRASE_PREF).setVisible(false); - findPreference(TextSecurePreferences.PASSPHRASE_TIMEOUT_INTERVAL_PREF).setVisible(false); - findPreference(TextSecurePreferences.PASSPHRASE_TIMEOUT_PREF).setVisible(false); - - KeyguardManager keyguardManager = (KeyguardManager)getContext().getSystemService(Context.KEYGUARD_SERVICE); - if (Build.VERSION.SDK_INT < 16 || !keyguardManager.isKeyguardSecure()) { - ((SwitchPreferenceCompat)findPreference(TextSecurePreferences.SCREEN_LOCK)).setChecked(false); - findPreference(TextSecurePreferences.SCREEN_LOCK).setEnabled(false); - } - } else { - findPreference(TextSecurePreferences.SCREEN_LOCK).setVisible(false); - findPreference(TextSecurePreferences.SCREEN_LOCK_TIMEOUT).setVisible(false); - } - } - - private class ScreenSecurityListener implements Preference.OnPreferenceChangeListener { @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - boolean enabled = (Boolean) newValue; - TextSecurePreferences.setScreenSecurityEnabled(getContext(), enabled); - Toast.makeText(getContext(), R.string.preferences__screen_security_restart_warning, Toast.LENGTH_LONG).show(); - return true; + public void onAttach(Activity activity) { + super.onAttach(activity); + ApplicationContext.getInstance(activity).injectDependencies(this); } - } - private class ScreenLockListener implements Preference.OnPreferenceChangeListener { @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - boolean enabled = (Boolean)newValue; - TextSecurePreferences.setScreenLockEnabled(getContext(), enabled); - - Intent intent = new Intent(getContext(), KeyCachingService.class); - intent.setAction(KeyCachingService.LOCK_TOGGLED_EVENT); - getContext().startService(intent); - return true; + public void onCreate(Bundle paramBundle) { + super.onCreate(paramBundle); + this.findPreference(TextSecurePreferences.SCREEN_LOCK).setOnPreferenceChangeListener(new ScreenLockListener()); + this.findPreference(TextSecurePreferences.CHANGE_PASSPHRASE_PREF).setOnPreferenceClickListener(new ChangePassphraseClickListener()); + this.findPreference(TextSecurePreferences.SCREEN_LOCK_TIMEOUT_INTERVAL_PREF).setOnPreferenceClickListener(new LockIntervalClickListener()); + this.findPreference(TextSecurePreferences.SCREEN_SECURITY_PREF).setOnPreferenceChangeListener(new ScreenSecurityListener()); + this.findPreference(TextSecurePreferences.READ_RECEIPTS_PREF).setOnPreferenceChangeListener(new ReadReceiptToggleListener()); + this.findPreference(PREFERENCE_CATEGORY_BLOCKED).setOnPreferenceClickListener(new BlockedContactsClickListener()); + + initializeVisibility(); } - } - - private class ScreenLockTimeoutListener implements Preference.OnPreferenceClickListener { @Override - public boolean onPreferenceClick(Preference preference) { - new TimeDurationPickerDialog(getContext(), (view, duration) -> { - if (duration == 0) { - TextSecurePreferences.setScreenLockTimeout(getContext(), 0); - } else { - long timeoutSeconds = Math.max(TimeUnit.MILLISECONDS.toSeconds(duration), 60); - TextSecurePreferences.setScreenLockTimeout(getContext(), timeoutSeconds); - } - - initializeScreenLockTimeoutSummary(); - }, 0).show(); - - return true; + public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(R.xml.preferences_app_protection); } - } - private class AccountLockClickListener implements Preference.OnPreferenceClickListener { @Override - public boolean onPreferenceClick(Preference preference) { - if (((SwitchPreferenceCompat)preference).isChecked()) { - RegistrationLockDialog.showRegistrationUnlockPrompt(getContext(), (SwitchPreferenceCompat)preference, accountManager); - } else { - RegistrationLockDialog.showRegistrationLockPrompt(getContext(), (SwitchPreferenceCompat)preference, accountManager); - } - - return true; + public void onResume() { + super.onResume(); + ((ApplicationPreferencesActivity) getActivity()).getSupportActionBar().setTitle(R.string.preferences__privacy); + initializePassphraseTimeoutSummary(); } - } - private class BlockedContactsClickListener implements Preference.OnPreferenceClickListener { - @Override - public boolean onPreferenceClick(Preference preference) { - Intent intent = new Intent(getActivity(), BlockedContactsActivity.class); - startActivity(intent); - return true; + private void initializePassphraseTimeoutSummary() { + int timeoutSeconds = TextSecurePreferences.getScreenLockTimeoutInterval(getActivity()); + this.findPreference(TextSecurePreferences.SCREEN_LOCK_TIMEOUT_INTERVAL_PREF) + .setSummary(getResources().getQuantityString(R.plurals.AppProtectionPreferenceFragment_minutes, timeoutSeconds, timeoutSeconds / 60)); } - } - - private class ReadReceiptToggleListener implements Preference.OnPreferenceChangeListener { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - boolean enabled = (boolean)newValue; - ApplicationContext.getInstance(getContext()) - .getJobManager() - .add(new MultiDeviceReadReceiptUpdateJob(getContext(), enabled)); - return true; + private void initializeVisibility() { + KeyguardManager keyguardManager = (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE); + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP || keyguardManager == null || !keyguardManager.isKeyguardSecure()) { + SwitchPreferenceCompat screenLockPreference = (SwitchPreferenceCompat) findPreference(TextSecurePreferences.SCREEN_LOCK); + screenLockPreference.setChecked(false); + screenLockPreference.setEnabled(false); + SwitchPreferenceCompat timeoutPreference = (SwitchPreferenceCompat) findPreference(TextSecurePreferences.PASSPHRASE_TIMEOUT_PREF); + timeoutPreference.setChecked(false); + timeoutPreference.setEnabled(false); + findPreference(TextSecurePreferences.SCREEN_LOCK_TIMEOUT_INTERVAL_PREF).setEnabled(false); + } } - } - - public static CharSequence getSummary(Context context) { - final int privacySummaryResId = R.string.ApplicationPreferencesActivity_privacy_summary; - final String onRes = context.getString(R.string.ApplicationPreferencesActivity_on); - final String offRes = context.getString(R.string.ApplicationPreferencesActivity_off); - if (TextSecurePreferences.isPasswordDisabled(context) && !TextSecurePreferences.isScreenLockEnabled(context)) { - return context.getString(privacySummaryResId, offRes, offRes); - } else { - return context.getString(privacySummaryResId, onRes, offRes); + private class ScreenSecurityListener implements Preference.OnPreferenceChangeListener { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + boolean enabled = (Boolean) newValue; + TextSecurePreferences.setScreenSecurityEnabled(getContext(), enabled); + Toast.makeText(getContext(), R.string.preferences__screen_security_restart_warning, Toast.LENGTH_LONG).show(); + return true; + } } - } - - // Derecated - - private class ChangePassphraseClickListener implements Preference.OnPreferenceClickListener { - @Override - public boolean onPreferenceClick(Preference preference) { - if (MasterSecretUtil.isPassphraseInitialized(getActivity())) { - startActivity(new Intent(getActivity(), PassphraseChangeActivity.class)); - } else { - Toast.makeText(getActivity(), - R.string.ApplicationPreferenceActivity_you_havent_set_a_passphrase_yet, - Toast.LENGTH_LONG).show(); - } - return true; + private class ScreenLockListener implements Preference.OnPreferenceChangeListener { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + boolean enabled = (Boolean) newValue; + TextSecurePreferences.setScreenLockEnabled(getContext(), enabled); + return true; + } } - } - private class PassphraseIntervalClickListener implements Preference.OnPreferenceClickListener { + private class BlockedContactsClickListener implements Preference.OnPreferenceClickListener { + @Override + public boolean onPreferenceClick(Preference preference) { + Intent intent = new Intent(getActivity(), BlockedContactsActivity.class); + startActivity(intent); + return true; + } + } - @Override - public boolean onPreferenceClick(Preference preference) { - new TimeDurationPickerDialog(getContext(), (view, duration) -> { - int timeoutMinutes = Math.max((int)TimeUnit.MILLISECONDS.toMinutes(duration), 1); + private class ReadReceiptToggleListener implements Preference.OnPreferenceChangeListener { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + boolean enabled = (boolean) newValue; + ApplicationContext.getInstance(getContext()) + .getJobManager() + .add(new MultiDeviceReadReceiptUpdateJob(getContext(), enabled)); - TextSecurePreferences.setPassphraseTimeoutInterval(getActivity(), timeoutMinutes); + return true; + } + } - initializePassphraseTimeoutSummary(); + public static CharSequence getSummary(Context context) { + final int privacySummaryResId = R.string.ApplicationPreferencesActivity_privacy_summary; + final String onRes = context.getString(R.string.ApplicationPreferencesActivity_on); + final String offRes = context.getString(R.string.ApplicationPreferencesActivity_off); - }, 0).show(); + if (TextSecurePreferences.isPasswordDisabled(context) && !TextSecurePreferences.isScreenLockEnabled(context)) { + return context.getString(privacySummaryResId, offRes, offRes); + } else { + return context.getString(privacySummaryResId, onRes, offRes); + } + } - return true; + private class ChangePassphraseClickListener implements Preference.OnPreferenceClickListener { + @Override + public boolean onPreferenceClick(Preference preference) { + Intent intent = new Intent(Settings.ACTION_SECURITY_SETTINGS); + startActivity(intent); + return true; + } } - } - private class DisablePassphraseClickListener implements Preference.OnPreferenceChangeListener { - @Override - public boolean onPreferenceChange(final Preference preference, Object newValue) { - if (((CheckBoxPreference)preference).isChecked()) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle(R.string.ApplicationPreferencesActivity_disable_passphrase); - builder.setMessage(R.string.ApplicationPreferencesActivity_this_will_permanently_unlock_signal_and_message_notifications); - builder.setIconAttribute(R.attr.dialog_alert_icon); - builder.setPositiveButton(R.string.ApplicationPreferencesActivity_disable, (dialog, which) -> { - MasterSecretUtil.changeMasterSecretPassphrase(getActivity(), - KeyCachingService.getMasterSecret(getContext()), - MasterSecretUtil.UNENCRYPTED_PASSPHRASE); + private class LockIntervalClickListener implements Preference.OnPreferenceClickListener { + + @Override + public boolean onPreferenceClick(Preference preference) { + new TimeDurationPickerDialog(getContext(), (view, duration) -> { + int timeoutSeconds = (int) Math.max(TimeUnit.MILLISECONDS.toSeconds(duration), 60); - TextSecurePreferences.setPasswordDisabled(getActivity(), true); - ((CheckBoxPreference)preference).setChecked(false); + TextSecurePreferences.setScreenLockTimeoutInterval(getActivity(), timeoutSeconds); - Intent intent = new Intent(getActivity(), KeyCachingService.class); - intent.setAction(KeyCachingService.DISABLE_ACTION); - getActivity().startService(intent); + initializePassphraseTimeoutSummary(); - initializeVisibility(); - }); - builder.setNegativeButton(android.R.string.cancel, null); - builder.show(); - } else { - Intent intent = new Intent(getActivity(), PassphraseChangeActivity.class); - startActivity(intent); - } + }, 0).show(); - return false; + return true; + } } - } } diff --git a/src/org/thoughtcrime/securesms/service/KeyCachingService.java b/src/org/thoughtcrime/securesms/service/KeyCachingService.java index 78d0e56a8e..8ab8e48d37 100644 --- a/src/org/thoughtcrime/securesms/service/KeyCachingService.java +++ b/src/org/thoughtcrime/securesms/service/KeyCachingService.java @@ -245,7 +245,7 @@ private void startTimeoutIfAppropriate() { (timeoutEnabled && !TextSecurePreferences.isPasswordDisabled(this)) || (screenTimeout >= 60 && TextSecurePreferences.isScreenLockEnabled(this))) { - long passphraseTimeoutMinutes = TextSecurePreferences.getPassphraseTimeoutInterval(this); + long passphraseTimeoutMinutes = TextSecurePreferences.getScreenLockTimeoutInterval(this); long screenLockTimeoutSeconds = TextSecurePreferences.getScreenLockTimeout(this); long timeoutMillis; diff --git a/src/org/thoughtcrime/securesms/util/ScreenLockUtil.java b/src/org/thoughtcrime/securesms/util/ScreenLockUtil.java new file mode 100644 index 0000000000..10dd1a5829 --- /dev/null +++ b/src/org/thoughtcrime/securesms/util/ScreenLockUtil.java @@ -0,0 +1,54 @@ +package org.thoughtcrime.securesms.util; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.app.KeyguardManager; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import java.util.Timer; +import java.util.TimerTask; + +public class ScreenLockUtil { + + public static final int REQUEST_CODE_CONFIRM_CREDENTIALS = 1001; + + public static boolean shouldLockApp = true; + + @TargetApi(21) + public static void applyScreenLock(Activity activity) { + KeyguardManager keyguardManager = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE); + Intent intent; + if (keyguardManager != null) { + intent = keyguardManager.createConfirmDeviceCredentialIntent(null, null); + if (intent != null) { + activity.startActivityForResult(intent, REQUEST_CODE_CONFIRM_CREDENTIALS); + } + } + } + + public static boolean isScreenLockEnabled(Context context) { + return TextSecurePreferences.isScreenLockEnabled(context) + && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP; + } + + public static Timer scheduleScreenLockTimer(Timer timer, Activity activity) { + cancelScreenLockTimer(timer); + Timer newTimer = new Timer(); + newTimer.schedule(new TimerTask() { + @Override + public void run() { + ScreenLockUtil.applyScreenLock(activity); + } + }, TextSecurePreferences.getScreenLockTimeoutInterval(activity) * 1000); + return newTimer; + } + + public static void cancelScreenLockTimer(Timer timer) { + if (timer != null) { + timer.cancel(); + } + } + +} diff --git a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java index cb37590b54..e648795ebd 100644 --- a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java +++ b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java @@ -60,7 +60,7 @@ public class TextSecurePreferences { private static final String LED_BLINK_PREF_CUSTOM = "pref_led_blink_custom"; public static final String ALL_MMS_PREF = "pref_all_mms"; public static final String ALL_SMS_PREF = "pref_all_sms"; - public static final String PASSPHRASE_TIMEOUT_INTERVAL_PREF = "pref_timeout_interval"; + public static final String SCREEN_LOCK_TIMEOUT_INTERVAL_PREF = "pref_timeout_interval"; public static final String PASSPHRASE_TIMEOUT_PREF = "pref_timeout_passphrase"; public static final String SCREEN_SECURITY_PREF = "pref_screen_security"; private static final String ENTER_SENDS_PREF = "pref_enter_sends"; @@ -702,12 +702,12 @@ public static boolean isPassphraseTimeoutEnabled(Context context) { return getBooleanPreference(context, PASSPHRASE_TIMEOUT_PREF, false); } - public static int getPassphraseTimeoutInterval(Context context) { - return getIntegerPreference(context, PASSPHRASE_TIMEOUT_INTERVAL_PREF, 5 * 60); + public static int getScreenLockTimeoutInterval(Context context) { + return getIntegerPreference(context, SCREEN_LOCK_TIMEOUT_INTERVAL_PREF, 5 * 60); } - public static void setPassphraseTimeoutInterval(Context context, int interval) { - setIntegerPrefrence(context, PASSPHRASE_TIMEOUT_INTERVAL_PREF, interval); + public static void setScreenLockTimeoutInterval(Context context, int interval) { + setIntegerPrefrence(context, SCREEN_LOCK_TIMEOUT_INTERVAL_PREF, interval); } public static String getLanguage(Context context) {