183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon/*
283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon * Copyright (C) 2015 The Android Open Source Project
383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon *
483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon * you may not use this file except in compliance with the License.
683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon * You may obtain a copy of the License at
783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon *
883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon *      http://www.apache.org/licenses/LICENSE-2.0
983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon *
1083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon * Unless required by applicable law or agreed to in writing, software
1183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
1283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon * See the License for the specific language governing permissions and
1483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon * limitations under the License.
1583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon */
1683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
1783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonpackage com.android.dialer.dialpad;
1883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
1983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport android.animation.Animator;
2083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport android.animation.Animator.AnimatorListener;
2183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport android.animation.ArgbEvaluator;
2283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport android.animation.ValueAnimator;
2383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport android.animation.ValueAnimator.AnimatorUpdateListener;
2483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport android.content.Context;
2583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport android.graphics.Color;
2683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport android.graphics.ColorFilter;
2783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport android.graphics.LightingColorFilter;
2883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport android.os.Handler;
2983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport android.os.Vibrator;
3083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport android.view.View;
3183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
3283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonimport com.android.dialer.R;
3383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
3483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon/**
3583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon * Animates the dial button on "emergency" phone numbers.
3683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon */
3783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordonpublic class PseudoEmergencyAnimator {
3883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    public interface ViewProvider {
3983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        View getView();
4083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    }
4183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
4283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    public static final String PSEUDO_EMERGENCY_NUMBER = "01189998819991197253";
4383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
4483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    private static final int VIBRATE_LENGTH_MILLIS = 200;
4583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    private static final int ITERATION_LENGTH_MILLIS = 1000;
4683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    private static final int ANIMATION_ITERATION_COUNT = 6;
4783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
4883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    private ViewProvider mViewProvider;
4983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    private ValueAnimator mPseudoEmergencyColorAnimator;
5083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
5183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    PseudoEmergencyAnimator(ViewProvider viewProvider) {
5283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        mViewProvider = viewProvider;
5383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    }
5483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
5583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    public void destroy() {
5683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        end();
5783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        mViewProvider = null;
5883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    }
5983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
6083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    public void start() {
6183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        if (mPseudoEmergencyColorAnimator == null) {
6283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            Integer colorFrom = Color.BLUE;
6383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            Integer colorTo = Color.RED;
6483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            mPseudoEmergencyColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
6583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
6683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            mPseudoEmergencyColorAnimator.addUpdateListener(new AnimatorUpdateListener() {
6783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                @Override
6883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                public void onAnimationUpdate(ValueAnimator animator) {
6983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                    try {
7083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        int color = (int) animator.getAnimatedValue();
7183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        ColorFilter colorFilter =
7283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                                new LightingColorFilter(Color.BLACK, color);
7383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
7483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        View floatingActionButtonContainer = getView().findViewById(
7583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                                R.id.dialpad_floating_action_button_container);
7683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        if (floatingActionButtonContainer != null) {
7783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                            floatingActionButtonContainer.getBackground().setColorFilter(
7883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                                    colorFilter);
7983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        }
8083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                    } catch (Exception e) {
8183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        animator.cancel();
8283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                    }
8383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                }
8483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            });
8583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
8683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            mPseudoEmergencyColorAnimator.addListener(new AnimatorListener() {
8783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                @Override
8883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                public void onAnimationCancel(Animator animation) { }
8983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
9083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                @Override
9183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                public void onAnimationRepeat(Animator animation) {
9283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                    try {
9383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        vibrate(VIBRATE_LENGTH_MILLIS);
9483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                    } catch (Exception e) {
9583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        animation.cancel();
9683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                    }
9783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                }
9883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
9983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                @Override
10083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                public void onAnimationStart(Animator animation) { }
10183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
10283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                @Override
10383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                public void onAnimationEnd(Animator animation) {
10483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                    try {
10583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        View floatingActionButtonContainer = getView().findViewById(
10683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                                R.id.dialpad_floating_action_button_container);
10783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        if (floatingActionButtonContainer != null) {
10883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                            floatingActionButtonContainer.getBackground().clearColorFilter();
10983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        }
11083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
11183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        new Handler().postDelayed(new Runnable() {
11283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                            @Override public void run() {
11383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                                try {
11483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                                    vibrate(VIBRATE_LENGTH_MILLIS);
11583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                                } catch (Exception e) {
11683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                                    // ignored
11783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                                }
11883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                            }
11983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        }, ITERATION_LENGTH_MILLIS);
12083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                    } catch (Exception e) {
12183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                        animation.cancel();
12283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                    }
12383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                }
12483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            });
12583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
12683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            mPseudoEmergencyColorAnimator.setDuration(VIBRATE_LENGTH_MILLIS);
12783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            mPseudoEmergencyColorAnimator.setRepeatMode(ValueAnimator.REVERSE);
12883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            mPseudoEmergencyColorAnimator.setRepeatCount(ANIMATION_ITERATION_COUNT);
12983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        }
13083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        if (!mPseudoEmergencyColorAnimator.isStarted()) {
13183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            mPseudoEmergencyColorAnimator.start();
13283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        }
13383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    }
13483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
13583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    public void end() {
13683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        if (mPseudoEmergencyColorAnimator != null && mPseudoEmergencyColorAnimator.isStarted()) {
13783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            mPseudoEmergencyColorAnimator.end();
13883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        }
13983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    }
14083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
14183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    private View getView() {
14283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        return mViewProvider == null ? null : mViewProvider.getView();
14383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    }
14483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
14583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    private Context getContext() {
14683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        View view = getView();
14783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        return view != null ? view.getContext() : null;
14883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    }
14983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon
15083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    private void vibrate(long milliseconds) {
15183131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        Context context = getContext();
15283131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        if (context != null) {
15383131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            Vibrator vibrator =
15483131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                    (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
15583131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            if (vibrator != null) {
15683131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon                vibrator.vibrate(milliseconds);
15783131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon            }
15883131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon        }
15983131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon    }
16083131715419e89eebe8e4ea7ada7f96ec37dd8f9Santos Cordon}
161