Home | History | Annotate | Download | only in shadows
      1 package org.robolectric.shadows;
      2 
      3 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
      4 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
      5 import static android.os.Build.VERSION_CODES.KITKAT_WATCH;
      6 import static android.os.Build.VERSION_CODES.LOLLIPOP;
      7 import static android.os.Build.VERSION_CODES.N_MR1;
      8 import static android.os.Build.VERSION_CODES.O;
      9 import static android.os.Build.VERSION_CODES.P;
     10 
     11 import android.media.AudioAttributes;
     12 import android.os.Build.VERSION_CODES;
     13 import android.os.Handler;
     14 import android.os.Looper;
     15 import android.os.SystemVibrator;
     16 import android.os.VibrationEffect;
     17 import org.robolectric.RuntimeEnvironment;
     18 import org.robolectric.annotation.Implementation;
     19 import org.robolectric.annotation.Implements;
     20 import org.robolectric.util.ReflectionHelpers;
     21 
     22 @Implements(value = SystemVibrator.class, isInAndroidSdk = false)
     23 public class ShadowSystemVibrator extends ShadowVibrator {
     24 
     25   private Handler handler = new Handler(Looper.myLooper());
     26   private Runnable stopVibratingRunnable = () -> vibrating = false;
     27 
     28   @Implementation
     29   protected boolean hasVibrator() {
     30     return hasVibrator;
     31   }
     32 
     33   @Implementation(minSdk = O)
     34   protected boolean hasAmplitudeControl() {
     35     return hasAmplitudeControl;
     36   }
     37 
     38   @Implementation(maxSdk = JELLY_BEAN_MR1)
     39   protected void vibrate(long[] pattern, int repeat) {
     40     recordVibratePattern(pattern, repeat);
     41   }
     42 
     43   @Implementation(minSdk = JELLY_BEAN_MR2, maxSdk = KITKAT_WATCH)
     44   protected void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat) {
     45     recordVibratePattern(pattern, repeat);
     46   }
     47 
     48   @Implementation(minSdk = LOLLIPOP, maxSdk = N_MR1)
     49   protected void vibrate(int uid, String opPkg, long[] pattern, int repeat, AudioAttributes attributes) {
     50     recordVibratePattern(pattern, repeat);
     51   }
     52 
     53   @Implementation(maxSdk = JELLY_BEAN_MR1)
     54   public void vibrate(long milliseconds) {
     55     recordVibrate(milliseconds);
     56   }
     57 
     58   @Implementation(minSdk = JELLY_BEAN_MR2, maxSdk = KITKAT_WATCH)
     59   public void vibrate(int owningUid, String owningPackage, long milliseconds) {
     60     recordVibrate(milliseconds);
     61   }
     62 
     63   @Implementation(minSdk = LOLLIPOP, maxSdk = N_MR1)
     64   protected void vibrate(int uid, String opPkg, long milliseconds, AudioAttributes attributes) {
     65     recordVibrate(milliseconds);
     66   }
     67 
     68   @Implementation(minSdk = O, maxSdk = VERSION_CODES.P)
     69   protected void vibrate(int uid, String opPkg, VibrationEffect effect, AudioAttributes attributes) {
     70     vibrate(uid, opPkg, effect, null, attributes);
     71   }
     72 
     73   @Implementation(minSdk = VERSION_CODES.CUR_DEVELOPMENT)
     74   protected void vibrate(int uid, String opPkg, VibrationEffect effect,
     75       String reason, AudioAttributes attributes) {
     76     if (effect instanceof VibrationEffect.Waveform) {
     77       VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) effect;
     78       recordVibratePattern(waveform.getTimings(), waveform.getRepeatIndex());
     79 
     80     } else {
     81       VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) effect;
     82 
     83       long timing;
     84 
     85       if (RuntimeEnvironment.getApiLevel() >= P) {
     86         timing = oneShot.getDuration();
     87       } else {
     88         timing = ReflectionHelpers.callInstanceMethod(oneShot, "getTiming");
     89       }
     90 
     91       recordVibrate(timing);
     92     }
     93   }
     94 
     95   private void recordVibrate(long milliseconds) {
     96     vibrating = true;
     97     this.milliseconds = milliseconds;
     98     handler.removeCallbacks(stopVibratingRunnable);
     99     handler.postDelayed(stopVibratingRunnable, this.milliseconds);
    100   }
    101 
    102   private void recordVibratePattern(long[] pattern, int repeat) {
    103     vibrating = true;
    104     this.pattern = pattern;
    105     this.repeat = repeat;
    106     handler.removeCallbacks(stopVibratingRunnable);
    107     if (repeat < 0) {
    108       long endDelayMillis = 0;
    109       for (long t : pattern) {
    110         endDelayMillis += t;
    111       }
    112       handler.postDelayed(stopVibratingRunnable, endDelayMillis);
    113     }
    114   }
    115 
    116   @Implementation
    117   protected void cancel() {
    118     cancelled = true;
    119     vibrating = false;
    120     handler.removeCallbacks(stopVibratingRunnable);
    121   }
    122 }
    123