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