LockedController.java 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Nextcloud Talk application
  3. *
  4. * @author Mario Danic
  5. * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
  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 as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. package com.nextcloud.talk.controllers;
  21. import android.app.Activity;
  22. import android.app.KeyguardManager;
  23. import android.content.Context;
  24. import android.content.Intent;
  25. import android.os.Build;
  26. import android.util.Log;
  27. import android.view.LayoutInflater;
  28. import android.view.View;
  29. import android.view.ViewGroup;
  30. import androidx.annotation.NonNull;
  31. import androidx.annotation.RequiresApi;
  32. import androidx.biometric.BiometricPrompt;
  33. import autodagger.AutoInjector;
  34. import butterknife.OnClick;
  35. import com.nextcloud.talk.R;
  36. import com.nextcloud.talk.activities.MainActivity;
  37. import com.nextcloud.talk.application.NextcloudTalkApplication;
  38. import com.nextcloud.talk.controllers.base.BaseController;
  39. import com.nextcloud.talk.utils.SecurityUtils;
  40. import com.nextcloud.talk.utils.preferences.AppPreferences;
  41. import javax.inject.Inject;
  42. import java.util.concurrent.Executor;
  43. import java.util.concurrent.Executors;
  44. @AutoInjector(NextcloudTalkApplication.class)
  45. public class LockedController extends BaseController {
  46. public static final String TAG = "LockedController";
  47. private static final int REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS = 112;
  48. @Inject
  49. AppPreferences appPreferences;
  50. @Override
  51. protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) {
  52. return inflater.inflate(R.layout.controller_locked, container, false);
  53. }
  54. @RequiresApi(api = Build.VERSION_CODES.M)
  55. @Override
  56. protected void onViewBound(@NonNull View view) {
  57. super.onViewBound(view);
  58. NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
  59. if (getActionBar() != null) {
  60. getActionBar().hide();
  61. }
  62. showBiometricDialog();
  63. }
  64. @RequiresApi(api = Build.VERSION_CODES.M)
  65. @OnClick(R.id.unlockTextView)
  66. void unlock() {
  67. checkIfWeAreSecure();
  68. }
  69. @RequiresApi(api = Build.VERSION_CODES.M)
  70. private void showBiometricDialog() {
  71. Context context = getActivity();
  72. if (context != null) {
  73. final BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
  74. .setTitle(String.format(context.getString(R.string.nc_biometric_unlock), context.getString(R.string.nc_app_name)))
  75. .setNegativeButtonText(context.getString(R.string.nc_cancel))
  76. .build();
  77. Executor executor = Executors.newSingleThreadExecutor();
  78. final BiometricPrompt biometricPrompt = new BiometricPrompt((MainActivity) context, executor,
  79. new BiometricPrompt.AuthenticationCallback() {
  80. @Override
  81. public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
  82. super.onAuthenticationSucceeded(result);
  83. Log.d(TAG, "Fingerprint recognised successfully");
  84. getRouter().popCurrentController();
  85. }
  86. @Override
  87. public void onAuthenticationFailed() {
  88. super.onAuthenticationFailed();
  89. Log.d(TAG, "Fingerprint not recognised");
  90. }
  91. @Override
  92. public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
  93. super.onAuthenticationError(errorCode, errString);
  94. showAuthenticationScreen();
  95. }
  96. }
  97. );
  98. biometricPrompt.authenticate(promptInfo, SecurityUtils.getCryptoObject());
  99. }
  100. }
  101. @RequiresApi(api = Build.VERSION_CODES.M)
  102. private void checkIfWeAreSecure() {
  103. if (getActivity() != null) {
  104. KeyguardManager keyguardManager = (KeyguardManager) getActivity().getSystemService(Context.KEYGUARD_SERVICE);
  105. if (keyguardManager != null && keyguardManager.isKeyguardSecure() && appPreferences.getIsScreenLocked()) {
  106. if (!SecurityUtils.checkIfWeAreAuthenticated(appPreferences.getScreenLockTimeout())) {
  107. showBiometricDialog();
  108. }
  109. }
  110. }
  111. }
  112. private void showAuthenticationScreen() {
  113. if (getActivity() != null) {
  114. KeyguardManager keyguardManager = (KeyguardManager) getActivity().getSystemService(Context.KEYGUARD_SERVICE);
  115. Intent intent = keyguardManager.createConfirmDeviceCredentialIntent(null, null);
  116. if (intent != null) {
  117. startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS);
  118. }
  119. }
  120. }
  121. @Override
  122. public void onActivityResult(int requestCode, int resultCode, Intent data) {
  123. super.onActivityResult(requestCode, resultCode, data);
  124. if (requestCode == REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS ) {
  125. if (resultCode == Activity.RESULT_OK) {
  126. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  127. if (SecurityUtils.checkIfWeAreAuthenticated(appPreferences.getScreenLockTimeout())) {
  128. Log.d(TAG, "All went well, dismiss locked controller");
  129. getRouter().popCurrentController();
  130. }
  131. }
  132. } else {
  133. Log.d(TAG, "Authorization failed");
  134. }
  135. }
  136. }
  137. }