PassCodeManager.java 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /**
  2. * ownCloud Android client application
  3. *
  4. * @author David A. Velasco
  5. * Copyright (C) 2015 ownCloud Inc.
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2,
  9. * as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. package com.owncloud.android.authentication;
  21. import android.app.Activity;
  22. import android.content.Context;
  23. import android.content.Intent;
  24. import android.content.SharedPreferences;
  25. import android.os.Build;
  26. import android.os.PowerManager;
  27. import android.preference.PreferenceManager;
  28. import android.view.WindowManager;
  29. import com.owncloud.android.MainApp;
  30. import com.owncloud.android.ui.activity.FingerprintActivity;
  31. import com.owncloud.android.ui.activity.PassCodeActivity;
  32. import com.owncloud.android.ui.activity.Preferences;
  33. import java.util.HashSet;
  34. import java.util.Set;
  35. public class PassCodeManager {
  36. private static final Set<Class> exemptOfPasscodeActivities;
  37. static {
  38. exemptOfPasscodeActivities = new HashSet<>();
  39. exemptOfPasscodeActivities.add(PassCodeActivity.class);
  40. exemptOfPasscodeActivities.add(FingerprintActivity.class);
  41. // other activities may be exempted, if needed
  42. }
  43. private static final int PASS_CODE_TIMEOUT = 1000;
  44. // keeping a "low" positive value is the easiest way to prevent the pass code is requested on rotations
  45. private static PassCodeManager passCodeManagerInstance = null;
  46. private Long timestamp = 0l;
  47. private int visibleActivitiesCounter = 0;
  48. public static PassCodeManager getPassCodeManager() {
  49. if (passCodeManagerInstance == null) {
  50. passCodeManagerInstance = new PassCodeManager();
  51. }
  52. return passCodeManagerInstance;
  53. }
  54. protected PassCodeManager() {}
  55. public void onActivityCreated(Activity activity) {
  56. if (passCodeIsEnabled() || fingerprintIsEnabled()) {
  57. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
  58. } else {
  59. activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
  60. }
  61. }
  62. public void onActivityStarted(Activity activity) {
  63. if (!exemptOfPasscodeActivities.contains(activity.getClass()) && passCodeShouldBeRequested()) {
  64. Intent i = new Intent(MainApp.getAppContext(), PassCodeActivity.class);
  65. i.setAction(PassCodeActivity.ACTION_CHECK);
  66. i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
  67. activity.startActivity(i);
  68. }
  69. if (!exemptOfPasscodeActivities.contains(activity.getClass()) &&
  70. Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
  71. fingerprintShouldBeRequested() && FingerprintActivity.isFingerprintReady(MainApp.getAppContext())) {
  72. Intent i = new Intent(MainApp.getAppContext(), FingerprintActivity.class);
  73. i.setAction(PassCodeActivity.ACTION_CHECK);
  74. i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
  75. activity.startActivity(i);
  76. }
  77. visibleActivitiesCounter++; // keep it AFTER passCodeShouldBeRequested was checked
  78. }
  79. public void onActivityStopped(Activity activity) {
  80. if (visibleActivitiesCounter > 0) {
  81. visibleActivitiesCounter--;
  82. }
  83. setUnlockTimestamp();
  84. PowerManager powerMgr = (PowerManager) activity.getSystemService(Context.POWER_SERVICE);
  85. if ((passCodeIsEnabled() || fingerprintIsEnabled())&& powerMgr != null && !powerMgr.isScreenOn()) {
  86. activity.moveTaskToBack(true);
  87. }
  88. }
  89. private void setUnlockTimestamp() {
  90. timestamp = System.currentTimeMillis();
  91. }
  92. private boolean passCodeShouldBeRequested() {
  93. return (System.currentTimeMillis() - timestamp) > PASS_CODE_TIMEOUT && visibleActivitiesCounter <= 0 && passCodeIsEnabled();
  94. }
  95. private boolean passCodeIsEnabled() {
  96. SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(MainApp.getAppContext());
  97. return (appPrefs.getBoolean(PassCodeActivity.PREFERENCE_SET_PASSCODE, false));
  98. }
  99. private boolean fingerprintShouldBeRequested() {
  100. return (System.currentTimeMillis() - timestamp) > PASS_CODE_TIMEOUT && visibleActivitiesCounter <= 0 && fingerprintIsEnabled();
  101. }
  102. private boolean fingerprintIsEnabled() {
  103. SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(MainApp.getAppContext());
  104. return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
  105. appPrefs.getBoolean(Preferences.PREFERENCE_USE_FINGERPRINT, false);
  106. }
  107. }