diff options
Diffstat (limited to 'java/com/android/incallui/answer/impl/answermethod/TwoButtonMethod.java')
-rw-r--r-- | java/com/android/incallui/answer/impl/answermethod/TwoButtonMethod.java | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/java/com/android/incallui/answer/impl/answermethod/TwoButtonMethod.java b/java/com/android/incallui/answer/impl/answermethod/TwoButtonMethod.java new file mode 100644 index 000000000..67b1b9689 --- /dev/null +++ b/java/com/android/incallui/answer/impl/answermethod/TwoButtonMethod.java @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2016 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.incallui.answer.impl.answermethod; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.animation.ValueAnimator; +import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.os.Bundle; +import android.support.annotation.FloatRange; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.TextView; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import com.android.dialer.compat.ActivityCompat; +import com.android.incallui.answer.impl.answermethod.FlingUpDownTouchHandler.OnProgressChangedListener; +import com.android.incallui.util.AccessibilityUtil; + +/** Answer method that shows two buttons for answer/reject. */ +public class TwoButtonMethod extends AnswerMethod + implements OnClickListener, AnimatorUpdateListener { + + private static final String STATE_HINT_TEXT = "hintText"; + private static final String STATE_INCOMING_WILL_DISCONNECT = "incomingWillDisconnect"; + + private View answerButton; + private View answerLabel; + private View declineButton; + private View declineLabel; + private TextView hintTextView; + private boolean incomingWillDisconnect; + private boolean buttonClicked; + private CharSequence hintText; + @Nullable private FlingUpDownTouchHandler touchHandler; + + @Override + public void onCreate(@Nullable Bundle bundle) { + super.onCreate(bundle); + if (bundle != null) { + incomingWillDisconnect = bundle.getBoolean(STATE_INCOMING_WILL_DISCONNECT); + hintText = bundle.getCharSequence(STATE_HINT_TEXT); + } + } + + @Override + public void onSaveInstanceState(Bundle bundle) { + super.onSaveInstanceState(bundle); + bundle.putBoolean(STATE_INCOMING_WILL_DISCONNECT, incomingWillDisconnect); + bundle.putCharSequence(STATE_HINT_TEXT, hintText); + } + + @Nullable + @Override + public View onCreateView( + LayoutInflater layoutInflater, @Nullable ViewGroup viewGroup, @Nullable Bundle bundle) { + View view = layoutInflater.inflate(R.layout.two_button_method, viewGroup, false); + + hintTextView = (TextView) view.findViewById(R.id.two_button_hint_text); + updateHintText(); + + answerButton = view.findViewById(R.id.two_button_answer_button); + answerLabel = view.findViewById(R.id.two_button_answer_label); + declineButton = view.findViewById(R.id.two_button_decline_button); + declineLabel = view.findViewById(R.id.two_button_decline_label); + + boolean showLabels = getResources().getBoolean(R.bool.two_button_show_button_labels); + answerLabel.setVisibility(showLabels ? View.VISIBLE : View.GONE); + declineLabel.setVisibility(showLabels ? View.VISIBLE : View.GONE); + + answerButton.setOnClickListener(this); + declineButton.setOnClickListener(this); + + if (AccessibilityUtil.isTouchExplorationEnabled(getContext())) { + /* Falsing already handled by AccessibilityManager */ + touchHandler = + FlingUpDownTouchHandler.attach( + view, + new OnProgressChangedListener() { + @Override + public void onProgressChanged(@FloatRange(from = -1f, to = 1f) float progress) {} + + @Override + public void onTrackingStart() {} + + @Override + public void onTrackingStopped() {} + + @Override + public void onMoveReset(boolean showHint) {} + + @Override + public void onMoveFinish(boolean accept) { + if (accept) { + answerCall(); + } else { + rejectCall(); + } + } + + @Override + public boolean shouldUseFalsing(@NonNull MotionEvent downEvent) { + return false; + } + }, + null /* Falsing already handled by AccessibilityManager */); + touchHandler.setFlingEnabled(false); + } + return view; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (touchHandler != null) { + touchHandler.detach(); + touchHandler = null; + } + } + + @Override + public void setHintText(@Nullable CharSequence hintText) { + this.hintText = hintText; + updateHintText(); + } + + @Override + public void setShowIncomingWillDisconnect(boolean incomingWillDisconnect) { + this.incomingWillDisconnect = incomingWillDisconnect; + updateHintText(); + } + + private void updateHintText() { + if (hintTextView == null) { + return; + } + hintTextView.setVisibility( + ActivityCompat.isInMultiWindowMode(getActivity()) ? View.GONE : View.VISIBLE); + if (!TextUtils.isEmpty(hintText) && !buttonClicked) { + hintTextView.setText(hintText); + hintTextView.animate().alpha(1f).start(); + } else if (incomingWillDisconnect && !buttonClicked) { + hintTextView.setText(R.string.call_incoming_will_disconnect); + hintTextView.animate().alpha(1f).start(); + } else { + hintTextView.animate().alpha(0f).start(); + } + } + + @Override + public void onClick(View view) { + if (view == answerButton) { + answerCall(); + LogUtil.v("TwoButtonMethod.onClick", "Call answered"); + } else if (view == declineButton) { + rejectCall(); + LogUtil.v("TwoButtonMethod.onClick", "two_buttonMethod Call rejected"); + } else { + Assert.fail("Unknown click from view: " + view); + } + buttonClicked = true; + } + + private void answerCall() { + ValueAnimator animator = ValueAnimator.ofFloat(0, 1); + animator.addUpdateListener(this); + animator.addListener( + new AnimatorListenerAdapter() { + private boolean canceled; + + @Override + public void onAnimationCancel(Animator animation) { + canceled = true; + } + + @Override + public void onAnimationEnd(Animator animation) { + if (!canceled) { + getParent().answerFromMethod(); + } + } + }); + AnimatorSet animatorSet = new AnimatorSet(); + animatorSet.play(animator).with(createViewHideAnimation()); + animatorSet.start(); + } + + private void rejectCall() { + ValueAnimator animator = ValueAnimator.ofFloat(0, -1); + animator.addUpdateListener(this); + animator.addListener( + new AnimatorListenerAdapter() { + private boolean canceled; + + @Override + public void onAnimationCancel(Animator animation) { + canceled = true; + } + + @Override + public void onAnimationEnd(Animator animation) { + if (!canceled) { + getParent().rejectFromMethod(); + } + } + }); + AnimatorSet animatorSet = new AnimatorSet(); + animatorSet.play(animator).with(createViewHideAnimation()); + animatorSet.start(); + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + getParent().onAnswerProgressUpdate(((float) animation.getAnimatedValue())); + } + + private Animator createViewHideAnimation() { + ObjectAnimator answerButtonHide = + ObjectAnimator.ofPropertyValuesHolder( + answerButton, + PropertyValuesHolder.ofFloat(View.SCALE_X, 0f), + PropertyValuesHolder.ofFloat(View.SCALE_Y, 0f)); + + ObjectAnimator declineButtonHide = + ObjectAnimator.ofPropertyValuesHolder( + declineButton, + PropertyValuesHolder.ofFloat(View.SCALE_X, 0f), + PropertyValuesHolder.ofFloat(View.SCALE_Y, 0f)); + + ObjectAnimator answerLabelHide = ObjectAnimator.ofFloat(answerLabel, View.ALPHA, 0f); + + ObjectAnimator declineLabelHide = ObjectAnimator.ofFloat(declineLabel, View.ALPHA, 0f); + + ObjectAnimator hintHide = ObjectAnimator.ofFloat(hintTextView, View.ALPHA, 0f); + + AnimatorSet hideSet = new AnimatorSet(); + hideSet + .play(answerButtonHide) + .with(declineButtonHide) + .with(answerLabelHide) + .with(declineLabelHide) + .with(hintHide); + return hideSet; + } +} |