From 83131715419e89eebe8e4ea7ada7f96ec37dd8f9 Mon Sep 17 00:00:00 2001 From: Santos Cordon Date: Thu, 16 Apr 2015 21:25:35 -0700 Subject: "Emergency" dialpad behavior. Change-Id: I132a119238c8de7249a4944e6dda472b3851637e --- src/com/android/dialer/DialtactsActivity.java | 9 ++ .../android/dialer/dialpad/DialpadFragment.java | 32 ++++- .../dialer/dialpad/PseudoEmergencyAnimator.java | 160 +++++++++++++++++++++ 3 files changed, 197 insertions(+), 4 deletions(-) create mode 100644 src/com/android/dialer/dialpad/PseudoEmergencyAnimator.java diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java index aefe01f7a..47e52342a 100644 --- a/src/com/android/dialer/DialtactsActivity.java +++ b/src/com/android/dialer/DialtactsActivity.java @@ -1080,6 +1080,15 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O } mSearchView.setText(normalizedQuery); } + + try { + if (mDialpadFragment != null && mDialpadFragment.isVisible()) { + mDialpadFragment.process_quote_emergency_unquote(normalizedQuery); + } + } catch (Exception ignored) { + // Skip any exceptions for this piece of code + } + } @Override diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java index 89cab4162..766175c9b 100644 --- a/src/com/android/dialer/dialpad/DialpadFragment.java +++ b/src/com/android/dialer/dialpad/DialpadFragment.java @@ -22,7 +22,6 @@ import android.app.Dialog; import android.app.DialogFragment; import android.app.Fragment; import android.content.BroadcastReceiver; -import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; @@ -68,7 +67,6 @@ import android.widget.PopupMenu; import android.widget.RelativeLayout; import android.widget.TextView; -import com.android.contacts.common.ContactsUtils; import com.android.contacts.common.GeoUtil; import com.android.contacts.common.util.PermissionsUtil; import com.android.contacts.common.util.PhoneNumberFormatter; @@ -79,14 +77,13 @@ import com.android.dialer.NeededForReflection; import com.android.dialer.R; import com.android.dialer.SpecialCharSequenceMgr; import com.android.dialer.calllog.PhoneAccountUtils; -import com.android.dialer.util.IntentUtil; import com.android.dialer.util.DialerUtils; +import com.android.dialer.util.IntentUtil; import com.android.phone.common.CallLogAsync; import com.android.phone.common.HapticFeedback; import com.android.phone.common.animation.AnimUtils; import com.android.phone.common.dialpad.DialpadKeyButton; import com.android.phone.common.dialpad.DialpadView; - import com.google.common.annotations.VisibleForTesting; import java.util.HashSet; @@ -157,6 +154,7 @@ public class DialpadFragment extends Fragment /** Stream type used to play the DTMF tones off call, and mapped to the volume control keys */ private static final int DIAL_TONE_STREAM_TYPE = AudioManager.STREAM_DTMF; + private OnDialpadQueryChangedListener mDialpadQueryListener; private DialpadView mDialpadView; @@ -188,6 +186,7 @@ public class DialpadFragment extends Fragment */ private String mProhibitedPhoneNumberRegexp; + private PseudoEmergencyAnimator mPseudoEmergencyAnimator; // Last number dialed, retrieved asynchronously from the call DB // in onCreate. This number is displayed when the user hits the @@ -307,6 +306,7 @@ public class DialpadFragment extends Fragment if (mDialpadQueryListener != null) { mDialpadQueryListener.onDialpadQueryChanged(mDigits.getText().toString()); } + updateDeleteButtonEnabledState(); } @@ -722,6 +722,10 @@ public class DialpadFragment extends Fragment @Override public void onDestroy() { super.onDestroy(); + if (mPseudoEmergencyAnimator != null) { + mPseudoEmergencyAnimator.destroy(); + mPseudoEmergencyAnimator = null; + } ((Context) getActivity()).unregisterReceiver(mCallStateReceiver); } @@ -1659,4 +1663,24 @@ public class DialpadFragment extends Fragment public void setYFraction(float yFraction) { ((DialpadSlidingRelativeLayout) getView()).setYFraction(yFraction); } + + public void process_quote_emergency_unquote(String query) { + if (PseudoEmergencyAnimator.PSEUDO_EMERGENCY_NUMBER.equals(query)) { + if (mPseudoEmergencyAnimator == null) { + mPseudoEmergencyAnimator = new PseudoEmergencyAnimator( + new PseudoEmergencyAnimator.ViewProvider() { + @Override + public View getView() { + return DialpadFragment.this.getView(); + } + }); + } + mPseudoEmergencyAnimator.start(); + } else { + if (mPseudoEmergencyAnimator != null) { + mPseudoEmergencyAnimator.end(); + } + } + } + } diff --git a/src/com/android/dialer/dialpad/PseudoEmergencyAnimator.java b/src/com/android/dialer/dialpad/PseudoEmergencyAnimator.java new file mode 100644 index 000000000..d4f32b5d4 --- /dev/null +++ b/src/com/android/dialer/dialpad/PseudoEmergencyAnimator.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.dialer.dialpad; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.ArgbEvaluator; +import android.animation.ValueAnimator; +import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.content.Context; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.LightingColorFilter; +import android.os.Handler; +import android.os.Vibrator; +import android.view.View; + +import com.android.dialer.R; + +/** + * Animates the dial button on "emergency" phone numbers. + */ +public class PseudoEmergencyAnimator { + public interface ViewProvider { + View getView(); + } + + public static final String PSEUDO_EMERGENCY_NUMBER = "01189998819991197253"; + + private static final int VIBRATE_LENGTH_MILLIS = 200; + private static final int ITERATION_LENGTH_MILLIS = 1000; + private static final int ANIMATION_ITERATION_COUNT = 6; + + private ViewProvider mViewProvider; + private ValueAnimator mPseudoEmergencyColorAnimator; + + PseudoEmergencyAnimator(ViewProvider viewProvider) { + mViewProvider = viewProvider; + } + + public void destroy() { + end(); + mViewProvider = null; + } + + public void start() { + if (mPseudoEmergencyColorAnimator == null) { + Integer colorFrom = Color.BLUE; + Integer colorTo = Color.RED; + mPseudoEmergencyColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo); + + mPseudoEmergencyColorAnimator.addUpdateListener(new AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animator) { + try { + int color = (int) animator.getAnimatedValue(); + ColorFilter colorFilter = + new LightingColorFilter(Color.BLACK, color); + + View floatingActionButtonContainer = getView().findViewById( + R.id.dialpad_floating_action_button_container); + if (floatingActionButtonContainer != null) { + floatingActionButtonContainer.getBackground().setColorFilter( + colorFilter); + } + } catch (Exception e) { + animator.cancel(); + } + } + }); + + mPseudoEmergencyColorAnimator.addListener(new AnimatorListener() { + @Override + public void onAnimationCancel(Animator animation) { } + + @Override + public void onAnimationRepeat(Animator animation) { + try { + vibrate(VIBRATE_LENGTH_MILLIS); + } catch (Exception e) { + animation.cancel(); + } + } + + @Override + public void onAnimationStart(Animator animation) { } + + @Override + public void onAnimationEnd(Animator animation) { + try { + View floatingActionButtonContainer = getView().findViewById( + R.id.dialpad_floating_action_button_container); + if (floatingActionButtonContainer != null) { + floatingActionButtonContainer.getBackground().clearColorFilter(); + } + + new Handler().postDelayed(new Runnable() { + @Override public void run() { + try { + vibrate(VIBRATE_LENGTH_MILLIS); + } catch (Exception e) { + // ignored + } + } + }, ITERATION_LENGTH_MILLIS); + } catch (Exception e) { + animation.cancel(); + } + } + }); + + mPseudoEmergencyColorAnimator.setDuration(VIBRATE_LENGTH_MILLIS); + mPseudoEmergencyColorAnimator.setRepeatMode(ValueAnimator.REVERSE); + mPseudoEmergencyColorAnimator.setRepeatCount(ANIMATION_ITERATION_COUNT); + } + if (!mPseudoEmergencyColorAnimator.isStarted()) { + mPseudoEmergencyColorAnimator.start(); + } + } + + public void end() { + if (mPseudoEmergencyColorAnimator != null && mPseudoEmergencyColorAnimator.isStarted()) { + mPseudoEmergencyColorAnimator.end(); + } + } + + private View getView() { + return mViewProvider == null ? null : mViewProvider.getView(); + } + + private Context getContext() { + View view = getView(); + return view != null ? view.getContext() : null; + } + + private void vibrate(long milliseconds) { + Context context = getContext(); + if (context != null) { + Vibrator vibrator = + (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); + if (vibrator != null) { + vibrator.vibrate(milliseconds); + } + } + } +} -- cgit v1.2.3