PseudoEmergencyAnimator.java revision 06b6b56e9eaa91ebf757ea641e38a9c885fa40bd
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.dialer.app.dialpad;
18
19import android.animation.Animator;
20import android.animation.Animator.AnimatorListener;
21import android.animation.ArgbEvaluator;
22import android.animation.ValueAnimator;
23import android.animation.ValueAnimator.AnimatorUpdateListener;
24import android.content.Context;
25import android.graphics.Color;
26import android.graphics.ColorFilter;
27import android.graphics.LightingColorFilter;
28import android.os.Handler;
29import android.os.Vibrator;
30import android.view.View;
31import com.android.dialer.app.R;
32
33/** Animates the dial button on "emergency" phone numbers. */
34public class PseudoEmergencyAnimator {
35
36  public static final String PSEUDO_EMERGENCY_NUMBER = "01189998819991197253";
37  private static final int VIBRATE_LENGTH_MILLIS = 200;
38  private static final int ITERATION_LENGTH_MILLIS = 1000;
39  private static final int ANIMATION_ITERATION_COUNT = 6;
40  private ViewProvider mViewProvider;
41  private ValueAnimator mPseudoEmergencyColorAnimator;
42
43  PseudoEmergencyAnimator(ViewProvider viewProvider) {
44    mViewProvider = viewProvider;
45  }
46
47  public void destroy() {
48    end();
49    mViewProvider = null;
50  }
51
52  public void start() {
53    if (mPseudoEmergencyColorAnimator == null) {
54      Integer colorFrom = Color.BLUE;
55      Integer colorTo = Color.RED;
56      mPseudoEmergencyColorAnimator =
57          ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
58
59      mPseudoEmergencyColorAnimator.addUpdateListener(
60          new AnimatorUpdateListener() {
61            @Override
62            public void onAnimationUpdate(ValueAnimator animator) {
63              try {
64                int color = (int) animator.getAnimatedValue();
65                ColorFilter colorFilter = new LightingColorFilter(Color.BLACK, color);
66
67                View floatingActionButtonContainer =
68                    getView().findViewById(R.id.floating_action_button);
69                if (floatingActionButtonContainer != null) {
70                  floatingActionButtonContainer.getBackground().setColorFilter(colorFilter);
71                }
72              } catch (Exception e) {
73                animator.cancel();
74              }
75            }
76          });
77
78      mPseudoEmergencyColorAnimator.addListener(
79          new AnimatorListener() {
80            @Override
81            public void onAnimationCancel(Animator animation) {}
82
83            @Override
84            public void onAnimationRepeat(Animator animation) {
85              try {
86                vibrate(VIBRATE_LENGTH_MILLIS);
87              } catch (Exception e) {
88                animation.cancel();
89              }
90            }
91
92            @Override
93            public void onAnimationStart(Animator animation) {}
94
95            @Override
96            public void onAnimationEnd(Animator animation) {
97              try {
98                View floatingActionButtonContainer =
99                    getView().findViewById(R.id.floating_action_button);
100                if (floatingActionButtonContainer != null) {
101                  floatingActionButtonContainer.getBackground().clearColorFilter();
102                }
103
104                new Handler()
105                    .postDelayed(
106                        new Runnable() {
107                          @Override
108                          public void run() {
109                            try {
110                              vibrate(VIBRATE_LENGTH_MILLIS);
111                            } catch (Exception e) {
112                              // ignored
113                            }
114                          }
115                        },
116                        ITERATION_LENGTH_MILLIS);
117              } catch (Exception e) {
118                animation.cancel();
119              }
120            }
121          });
122
123      mPseudoEmergencyColorAnimator.setDuration(VIBRATE_LENGTH_MILLIS);
124      mPseudoEmergencyColorAnimator.setRepeatMode(ValueAnimator.REVERSE);
125      mPseudoEmergencyColorAnimator.setRepeatCount(ANIMATION_ITERATION_COUNT);
126    }
127    if (!mPseudoEmergencyColorAnimator.isStarted()) {
128      mPseudoEmergencyColorAnimator.start();
129    }
130  }
131
132  public void end() {
133    if (mPseudoEmergencyColorAnimator != null && mPseudoEmergencyColorAnimator.isStarted()) {
134      mPseudoEmergencyColorAnimator.end();
135    }
136  }
137
138  private View getView() {
139    return mViewProvider == null ? null : mViewProvider.getView();
140  }
141
142  private Context getContext() {
143    View view = getView();
144    return view != null ? view.getContext() : null;
145  }
146
147  private void vibrate(long milliseconds) {
148    Context context = getContext();
149    if (context != null) {
150      Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
151      if (vibrator != null) {
152        vibrator.vibrate(milliseconds);
153      }
154    }
155  }
156
157  public interface ViewProvider {
158
159    View getView();
160  }
161}
162