소스 검색

PassCodeManager: convert to Kotlin, clean up, use injection

Signed-off-by: Álvaro Brey Vilas <alvaro.brey@nextcloud.com>
Álvaro Brey Vilas 3 년 전
부모
커밋
8b03556f71

+ 9 - 1
src/main/java/com/nextcloud/client/di/AppModule.java

@@ -51,6 +51,9 @@ import com.nextcloud.client.migrations.MigrationsManagerImpl;
 import com.nextcloud.client.network.ClientFactory;
 import com.nextcloud.client.network.ClientFactory;
 import com.nextcloud.client.notifications.AppNotificationManager;
 import com.nextcloud.client.notifications.AppNotificationManager;
 import com.nextcloud.client.notifications.AppNotificationManagerImpl;
 import com.nextcloud.client.notifications.AppNotificationManagerImpl;
+import com.nextcloud.client.preferences.AppPreferences;
+import com.nextcloud.client.utils.Throttler;
+import com.owncloud.android.authentication.PassCodeManager;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.UploadsStorageManager;
 import com.owncloud.android.datamodel.UploadsStorageManager;
@@ -61,7 +64,6 @@ import com.owncloud.android.ui.activities.data.activities.RemoteActivitiesReposi
 import com.owncloud.android.ui.activities.data.files.FilesRepository;
 import com.owncloud.android.ui.activities.data.files.FilesRepository;
 import com.owncloud.android.ui.activities.data.files.FilesServiceApiImpl;
 import com.owncloud.android.ui.activities.data.files.FilesServiceApiImpl;
 import com.owncloud.android.ui.activities.data.files.RemoteFilesRepository;
 import com.owncloud.android.ui.activities.data.files.RemoteFilesRepository;
-import com.nextcloud.client.utils.Throttler;
 
 
 import org.greenrobot.eventbus.EventBus;
 import org.greenrobot.eventbus.EventBus;
 
 
@@ -237,4 +239,10 @@ class AppModule {
     Throttler throttler(Clock clock) {
     Throttler throttler(Clock clock) {
         return new Throttler(clock);
         return new Throttler(clock);
     }
     }
+
+    @Provides
+    @Singleton
+    PassCodeManager passCodeManager(AppPreferences preferences) {
+        return new PassCodeManager(preferences);
+    }
 }
 }

+ 2 - 2
src/main/java/com/owncloud/android/MainApp.java

@@ -169,7 +169,8 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
     @Inject
     @Inject
     MigrationsManager migrationsManager;
     MigrationsManager migrationsManager;
 
 
-    private PassCodeManager passCodeManager;
+    @Inject
+    PassCodeManager passCodeManager;
 
 
     @SuppressWarnings("unused")
     @SuppressWarnings("unused")
     private boolean mBound;
     private boolean mBound;
@@ -261,7 +262,6 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
         DisplayUtils.useCompatVectorIfNeeded();
         DisplayUtils.useCompatVectorIfNeeded();
 
 
         fixStoragePath();
         fixStoragePath();
-        passCodeManager = new PassCodeManager(preferences);
 
 
         MainApp.storagePath = preferences.getStoragePath(getApplicationContext().getFilesDir().getAbsolutePath());
         MainApp.storagePath = preferences.getStoragePath(getApplicationContext().getFilesDir().getAbsolutePath());
 
 

+ 1 - 0
src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java

@@ -239,6 +239,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     @Inject AppPreferences preferences;
     @Inject AppPreferences preferences;
     @Inject OnboardingService onboarding;
     @Inject OnboardingService onboarding;
     @Inject DeviceInfo deviceInfo;
     @Inject DeviceInfo deviceInfo;
+    @Inject PassCodeManager passCodeManager;
     private boolean onlyAdd = false;
     private boolean onlyAdd = false;
     @SuppressLint("ResourceAsColor") @ColorInt
     @SuppressLint("ResourceAsColor") @ColorInt
     private int primaryColor = R.color.primary;
     private int primaryColor = R.color.primary;

+ 0 - 154
src/main/java/com/owncloud/android/authentication/PassCodeManager.java

@@ -1,154 +0,0 @@
-/*
- *   ownCloud Android client application
- *
- *   @author David A. Velasco
- *   Copyright (C) 2015 ownCloud Inc.
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License version 2,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-package com.owncloud.android.authentication;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.view.Window;
-import android.view.WindowManager;
-
-import com.nextcloud.client.preferences.AppPreferences;
-import com.nextcloud.client.preferences.AppPreferencesImpl;
-import com.owncloud.android.MainApp;
-import com.owncloud.android.ui.activity.PassCodeActivity;
-import com.owncloud.android.ui.activity.RequestCredentialsActivity;
-import com.owncloud.android.ui.activity.SettingsActivity;
-import com.owncloud.android.utils.DeviceCredentialUtils;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public final class PassCodeManager {
-
-    private static final Set<Class> exemptOfPasscodeActivities;
-
-    public static final int PASSCODE_ACTIVITY = 9999;
-
-    static {
-        exemptOfPasscodeActivities = new HashSet<>();
-        exemptOfPasscodeActivities.add(PassCodeActivity.class);
-        exemptOfPasscodeActivities.add(RequestCredentialsActivity.class);
-        // other activities may be exempted, if needed
-    }
-
-    /**
-     *  Keeping a "low" positive value is the easiest way to prevent
-     *  the pass code being requested on screen rotations.
-     */
-    private static final int PASS_CODE_TIMEOUT = 5000;
-
-    private AppPreferences preferences;
-    private int visibleActivitiesCounter = 0;
-
-
-    public PassCodeManager(AppPreferences preferences) {
-        this.preferences = preferences;
-    }
-
-    private boolean isExemptActivity(final Activity activity) {
-        return exemptOfPasscodeActivities.contains(activity.getClass());
-    }
-
-    private void setSecureFlag(Activity activity) {
-        Window window = activity.getWindow();
-        if (window != null) {
-            if (isPassCodeEnabled() || deviceCredentialsAreEnabled(activity)) {
-                window.addFlags(WindowManager.LayoutParams.FLAG_SECURE);
-            } else {
-                window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
-            }
-        }
-    }
-
-    public boolean onActivityStarted(Activity activity) {
-        boolean askedForPin = false;
-        Long timestamp = AppPreferencesImpl.fromContext(activity).getLockTimestamp();
-
-        setSecureFlag(activity);
-
-        if (!isExemptActivity(activity) && passCodeShouldBeRequested(timestamp)) {
-            askedForPin = true;
-
-            preferences.setLockTimestamp(0);
-
-            Intent i = new Intent(MainApp.getAppContext(), PassCodeActivity.class);
-            i.setAction(PassCodeActivity.ACTION_CHECK);
-            i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-            activity.startActivityForResult(i, PASSCODE_ACTIVITY);
-        }
-
-        if (!isExemptActivity(activity) &&
-            deviceCredentialsShouldBeRequested(timestamp, activity)) {
-            askedForPin = true;
-
-            preferences.setLockTimestamp(0);
-
-            Intent i = new Intent(MainApp.getAppContext(), RequestCredentialsActivity.class);
-            i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-            activity.startActivityForResult(i, PASSCODE_ACTIVITY);
-        } else {
-            if (!askedForPin && preferences.getLockTimestamp() != 0) {
-                preferences.setLockTimestamp(SystemClock.elapsedRealtime());
-            }
-        }
-
-        if (!isExemptActivity(activity)) {
-            visibleActivitiesCounter++;    // keep it AFTER passCodeShouldBeRequested was checked
-        }
-
-        return askedForPin;
-    }
-
-
-    public void onActivityStopped(Activity activity) {
-        if (visibleActivitiesCounter > 0 && !isExemptActivity(activity)) {
-            visibleActivitiesCounter--;
-        }
-
-        PowerManager powerMgr = (PowerManager) activity.getSystemService(Context.POWER_SERVICE);
-        if ((isPassCodeEnabled() || deviceCredentialsAreEnabled(activity)) && powerMgr != null
-            && !powerMgr.isScreenOn()) {
-            activity.moveTaskToBack(true);
-        }
-    }
-
-    private boolean passCodeShouldBeRequested(Long timestamp) {
-        return Math.abs(SystemClock.elapsedRealtime() - timestamp) > PASS_CODE_TIMEOUT &&
-            visibleActivitiesCounter <= 0 && isPassCodeEnabled();
-    }
-
-    private boolean isPassCodeEnabled() {
-        return SettingsActivity.LOCK_PASSCODE.equals(preferences.getLockPreference());
-    }
-
-    private boolean deviceCredentialsShouldBeRequested(Long timestamp, Activity activity) {
-        return Math.abs(SystemClock.elapsedRealtime() - timestamp) > PASS_CODE_TIMEOUT && visibleActivitiesCounter <= 0 &&
-            deviceCredentialsAreEnabled(activity);
-    }
-
-    private boolean deviceCredentialsAreEnabled(Activity activity) {
-        return SettingsActivity.LOCK_DEVICE_CREDENTIALS.equals(preferences.getLockPreference())
-            || (preferences.isFingerprintUnlockEnabled()
-            && DeviceCredentialUtils.areCredentialsAvailable(activity));
-    }
-}

+ 141 - 0
src/main/java/com/owncloud/android/authentication/PassCodeManager.kt

@@ -0,0 +1,141 @@
+/*
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package com.owncloud.android.authentication
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.os.PowerManager
+import android.os.SystemClock
+import android.view.WindowManager
+import com.nextcloud.client.preferences.AppPreferences
+import com.owncloud.android.MainApp
+import com.owncloud.android.ui.activity.PassCodeActivity
+import com.owncloud.android.ui.activity.RequestCredentialsActivity
+import com.owncloud.android.ui.activity.SettingsActivity
+import com.owncloud.android.utils.DeviceCredentialUtils
+import kotlin.math.abs
+
+@Suppress("TooManyFunctions")
+class PassCodeManager(private val preferences: AppPreferences) {
+    companion object {
+        private val exemptOfPasscodeActivities = setOf(
+            PassCodeActivity::class.java,
+            RequestCredentialsActivity::class.java
+        )
+        const val PASSCODE_ACTIVITY = 9999
+
+        /**
+         * Keeping a "low" positive value is the easiest way to prevent
+         * the pass code being requested on screen rotations.
+         */
+        private const val PASS_CODE_TIMEOUT = 5000
+    }
+
+    private var visibleActivitiesCounter = 0
+
+    private fun isExemptActivity(activity: Activity): Boolean {
+        return exemptOfPasscodeActivities.contains(activity.javaClass)
+    }
+
+    fun onActivityStarted(activity: Activity): Boolean {
+        var askedForPin = false
+        val timestamp = preferences.lockTimestamp
+        setSecureFlag(activity)
+
+        if (!isExemptActivity(activity)) {
+            if (passCodeShouldBeRequested(timestamp)) {
+                askedForPin = true
+                preferences.lockTimestamp = 0
+                requestPasscode(activity)
+            }
+            if (deviceCredentialsShouldBeRequested(timestamp, activity)) {
+                askedForPin = true
+                preferences.lockTimestamp = 0
+                requestCredentials(activity)
+            }
+        }
+
+        if (!askedForPin && preferences.lockTimestamp != 0L) {
+            preferences.lockTimestamp = SystemClock.elapsedRealtime()
+        }
+
+        if (!isExemptActivity(activity)) {
+            visibleActivitiesCounter++ // keep it AFTER passCodeShouldBeRequested was checked
+        }
+        return askedForPin
+    }
+
+    private fun setSecureFlag(activity: Activity) {
+        val window = activity.window
+        if (window != null) {
+            if (isPassCodeEnabled() || deviceCredentialsAreEnabled(activity)) {
+                window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
+            } else {
+                window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
+            }
+        }
+    }
+
+    private fun requestPasscode(activity: Activity) {
+        val i = Intent(MainApp.getAppContext(), PassCodeActivity::class.java)
+        i.action = PassCodeActivity.ACTION_CHECK
+        i.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
+        activity.startActivityForResult(i, PASSCODE_ACTIVITY)
+    }
+
+    private fun requestCredentials(activity: Activity) {
+        val i = Intent(MainApp.getAppContext(), RequestCredentialsActivity::class.java)
+        i.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
+        activity.startActivityForResult(i, PASSCODE_ACTIVITY)
+    }
+
+    fun onActivityStopped(activity: Activity) {
+        if (visibleActivitiesCounter > 0 && !isExemptActivity(activity)) {
+            visibleActivitiesCounter--
+        }
+        val powerMgr = activity.getSystemService(Context.POWER_SERVICE) as PowerManager
+        if ((isPassCodeEnabled() || deviceCredentialsAreEnabled(activity)) && !powerMgr?.isScreenOn) {
+            activity.moveTaskToBack(true)
+        }
+    }
+
+    /**
+     * `true` if the time elapsed since last unlock is longer than [PASS_CODE_TIMEOUT] and no activities are visible
+     */
+    private fun shouldBeLocked(timestamp: Long) =
+        abs(SystemClock.elapsedRealtime() - timestamp) > PASS_CODE_TIMEOUT &&
+            visibleActivitiesCounter <= 0
+
+    private fun passCodeShouldBeRequested(timestamp: Long): Boolean {
+        return shouldBeLocked(timestamp) && isPassCodeEnabled()
+    }
+
+    private fun isPassCodeEnabled(): Boolean = SettingsActivity.LOCK_PASSCODE == preferences.lockPreference
+
+    private fun deviceCredentialsShouldBeRequested(timestamp: Long, activity: Activity): Boolean {
+        return shouldBeLocked(timestamp) && deviceCredentialsAreEnabled(activity)
+    }
+
+    private fun deviceCredentialsAreEnabled(activity: Activity): Boolean {
+        return SettingsActivity.LOCK_DEVICE_CREDENTIALS == preferences.lockPreference ||
+            (preferences.isFingerprintUnlockEnabled && DeviceCredentialUtils.areCredentialsAvailable(activity))
+    }
+}