Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add haptic feedback toggle for code refresh #1599

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.VIBRATE" />

<!-- NOTE: Disabled for now. See issue: #1047
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/com/beemdevelopment/aegis/Preferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ public boolean isEntryHighlightEnabled() {
return _prefs.getBoolean("pref_highlight_entry", false);
}

public boolean isHapticFeedbackEnabled() {
return _prefs.getBoolean("pref_haptic_feedback", true);
}

public boolean isPauseFocusedEnabled() {
boolean dependenciesEnabled = isTapToRevealEnabled() || isEntryHighlightEnabled();
if (!dependenciesEnabled) return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.beemdevelopment.aegis;

public class VibrationPatterns {
private VibrationPatterns() {}

public static final long[] EXPIRING = {475, 20, 5, 20, 965, 20, 5, 20, 965, 20, 5, 20, 420};
public static final long[] REFRESH_CODE = {0, 100};
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ public void start() {
}
_running = true;

_listener.onRefresh();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure we can remove this?

_handler.postDelayed(new Runnable() {
@Override
public void run() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.beemdevelopment.aegis.helpers;

import android.content.Context;
import android.os.Build;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.os.VibratorManager;

import com.beemdevelopment.aegis.Preferences;

import dagger.hilt.InstallIn;
import dagger.hilt.android.EarlyEntryPoint;
import dagger.hilt.android.EarlyEntryPoints;
import dagger.hilt.components.SingletonComponent;

public class VibrationHelper {
public static void vibratePattern(Context context, long[] pattern) {
if (!isHapticFeedbackEnabled(context)) {
return;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
VibratorManager vibratorManager = (VibratorManager) context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE);
if (vibratorManager != null) {
Vibrator vibrator = vibratorManager.getDefaultVibrator();
VibrationEffect effect = VibrationEffect.createWaveform(pattern, -1);
vibrator.vibrate(effect);
}
} else {
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
VibrationEffect effect = VibrationEffect.createWaveform(pattern, -1);
vibrator.vibrate(effect);
}
}
}
}

public static boolean isHapticFeedbackEnabled(Context context) {
Preferences _prefs = EarlyEntryPoints.get(context.getApplicationContext(), PrefEntryPoint.class).getPreferences();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't really what EarlyEntryPoints is meant for. I would suggest simply initializing a new Preferences based on the context. If it turns out we can move the vibration trigger to UiRefresher, we can do this once in the constructor of VibrationHelper.


return _prefs.isHapticFeedbackEnabled();
}

@EarlyEntryPoint
@InstallIn(SingletonComponent.class)
public interface PrefEntryPoint {
Preferences getPreferences();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.beemdevelopment.aegis.ui.views;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
Expand All @@ -25,11 +27,13 @@
import com.beemdevelopment.aegis.AccountNamePosition;
import com.beemdevelopment.aegis.Preferences;
import com.beemdevelopment.aegis.R;
import com.beemdevelopment.aegis.VibrationPatterns;
import com.beemdevelopment.aegis.ViewMode;
import com.beemdevelopment.aegis.helpers.AnimationsHelper;
import com.beemdevelopment.aegis.helpers.CenterVerticalSpan;
import com.beemdevelopment.aegis.helpers.SimpleAnimationEndListener;
import com.beemdevelopment.aegis.helpers.UiRefresher;
import com.beemdevelopment.aegis.helpers.VibrationHelper;
import com.beemdevelopment.aegis.otp.HotpInfo;
import com.beemdevelopment.aegis.otp.OtpInfo;
import com.beemdevelopment.aegis.otp.OtpInfoException;
Expand Down Expand Up @@ -67,6 +71,7 @@ public class EntryHolder extends RecyclerView.ViewHolder {

private boolean _hidden;
private boolean _paused;
private boolean _nonUniform;

private TotpProgressBar _progressBar;
private MaterialCardView _view;
Expand Down Expand Up @@ -118,12 +123,13 @@ public long getMillisTillNextRefresh() {
});
}

public void setData(VaultEntry entry, Preferences.CodeGrouping groupSize, ViewMode viewMode, AccountNamePosition accountNamePosition, boolean showIcon, boolean showProgress, boolean hidden, boolean paused, boolean dimmed, boolean showExpirationState, boolean showNextCode) {
public void setData(VaultEntry entry, Preferences.CodeGrouping groupSize, ViewMode viewMode, AccountNamePosition accountNamePosition, boolean showIcon, boolean nonUniform, boolean hidden, boolean paused, boolean dimmed, boolean showExpirationState, boolean showNextCode) {
_entry = entry;
_hidden = hidden;
_paused = paused;
_codeGrouping = groupSize;
_viewMode = viewMode;
_nonUniform = nonUniform;

_accountNamePosition = accountNamePosition;
if (viewMode.equals(ViewMode.TILES) && _accountNamePosition == AccountNamePosition.END) {
Expand All @@ -140,7 +146,7 @@ public void setData(VaultEntry entry, Preferences.CodeGrouping groupSize, ViewMo
_favoriteIndicator.setVisibility(_entry.isFavorite() ? View.VISIBLE : View.INVISIBLE);

// only show the progress bar if there is no uniform period and the entry type is TotpInfo
setShowProgress(showProgress);
setShowProgress(nonUniform);

// only show the button if this entry is of type HotpInfo
_buttonRefresh.setVisibility(entry.getInfo() instanceof HotpInfo ? View.VISIBLE : View.GONE);
Expand Down Expand Up @@ -457,6 +463,16 @@ public void startExpirationAnimation() {
final int blinkDuration = 3000;
ValueAnimator delayAnim2 = ValueAnimator.ofFloat(0f, 0f);
delayAnim2.setDuration((long) ((totalStateDuration - blinkDuration) / durationScale));
delayAnim2.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (!_nonUniform) {
if (itemView.isShown()) {
VibrationHelper.vibratePattern(itemView.getContext(), VibrationPatterns.EXPIRING);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This results in starting a vibration for every single entry.

Since we're not relying on repeated animation callbacks for the "ticks" of the vibration, I don't think we need to link this to the animation. Perhaps a second postDelayed in UiRefresher would do the trick? This would also make the vibrations work in case animations are disabled, which is currently not the case.

}
}
}
});

ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(_profileCode, "alpha", 1f, .5f);
alphaAnim.setDuration((long) (500 / durationScale));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@
import com.beemdevelopment.aegis.Preferences;
import com.beemdevelopment.aegis.R;
import com.beemdevelopment.aegis.SortCategory;
import com.beemdevelopment.aegis.VibrationPatterns;
import com.beemdevelopment.aegis.ViewMode;
import com.beemdevelopment.aegis.helpers.AnimationsHelper;
import com.beemdevelopment.aegis.helpers.MetricsHelper;
import com.beemdevelopment.aegis.helpers.SimpleItemTouchHelperCallback;
import com.beemdevelopment.aegis.helpers.UiRefresher;
import com.beemdevelopment.aegis.helpers.VibrationHelper;
import com.beemdevelopment.aegis.otp.TotpInfo;
import com.beemdevelopment.aegis.ui.glide.GlideHelper;
import com.beemdevelopment.aegis.ui.models.ErrorCardInfo;
Expand Down Expand Up @@ -144,6 +146,10 @@ public int getSpanSize(int position) {
@Override
public void onRefresh() {
refresh(false);

if (_recyclerView.isShown()) {
VibrationHelper.vibratePattern(getContext(), VibrationPatterns.REFRESH_CODE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is only the case on my device, but I don't feel this vibration.

}
}

@Override
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@
<string name="note" comment="Users can add a note to an entry">Note</string>
<string name="clear">Clear</string>

<string name="pref_haptic_feedback_summary">Make your device vibrate when codes are refreshing</string>
<string name="pref_haptic_feedback_title">Haptic feedback</string>
<string name="pref_highlight_entry_title">Highlight tokens when tapped</string>
<string name="pref_highlight_entry_summary">Make tokens easier to distinguish from each other by temporarily highlighting them when tapped</string>
<string name="pref_minimize_on_copy_title">Minimize on copy</string>
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/res/xml/preferences_behavior.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
android:title="@string/pref_copy_behavior_title"
app:iconSpaceReserved="false"/>

<androidx.preference.SwitchPreferenceCompat
android:defaultValue="true"
android:key="pref_haptic_feedback"
android:title="@string/pref_haptic_feedback_title"
android:summary="@string/pref_haptic_feedback_summary"
app:iconSpaceReserved="false"/>

<androidx.preference.SwitchPreferenceCompat
android:defaultValue="false"
android:key="pref_highlight_entry"
Expand Down
Loading