diff options
author | Ta-wei Yen <twyen@google.com> | 2015-11-12 14:23:00 -0800 |
---|---|---|
committer | Ta-wei Yen <twyen@google.com> | 2015-11-13 16:10:50 -0800 |
commit | 37adc9854ae78a0dd358b8e129417c142b83cf1c (patch) | |
tree | 461fcb039af1140e78981b6152b6466e958abbb6 /InCallUI | |
parent | a1bccb179974a821a989b459326b182cd07b772e (diff) |
Use separate AnswerFragment for Talkback
+ Split AnswerFragment into GlowpadAnswerFragment and
AccessibleAnswerFragment, with the refactored AnswerFragment
as base class.
+ InCallActivity will select GlowpadAnswerFragment and
AccessibleAnswerFragment base on if any touch exploration
accessibility service is active.
+ Removed AnswerListener from GlowPadWrapper, as it is only
implemented in one class and made the code more complex.
+ Changed answer icon's color into green.
Bug:24101341
Change-Id: Ida2b07986d64d6442ff87a2258180846a092942e
Diffstat (limited to 'InCallUI')
9 files changed, 544 insertions, 171 deletions
diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml b/InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml index c615295ed..f22b87e34 100644 --- a/InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml +++ b/InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml @@ -14,7 +14,7 @@ limitations under the License. --> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:drawable="@drawable/fab_blue" /> + <item android:drawable="@drawable/fab_green"/> <item> <bitmap android:gravity="center" diff --git a/InCallUI/res/layout/accessible_answer_fragment.xml b/InCallUI/res/layout/accessible_answer_fragment.xml new file mode 100644 index 000000000..90fe57788 --- /dev/null +++ b/InCallUI/res/layout/accessible_answer_fragment.xml @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +~ Copyright (C) 2013 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 +--> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_horizontal" + android:background="@color/glowpad_background_color"> + <RelativeLayout + android:id="@+id/accessible_answer_fragment_answer" + android:orientation="vertical" + android:layout_width="120dp" + android:layout_height="120dp" + android:focusable="true" + android:focusableInTouchMode="true" + android:clickable="true" + android:layout_alignParentRight="true" + android:layout_centerVertical="true" + android:layout_marginLeft="16dp" + android:layout_marginRight="16dp"> + <ImageView + android:layout_width="64dp" + android:layout_height="64dp" + android:src="@drawable/ic_lockscreen_answer_activated_layer" + android:layout_centerInParent="true"> + </ImageView> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/description_target_answer" + android:textSize="12sp" + android:textColor="@color/accessible_answer_hint_text_color" + android:layout_alignParentBottom="true" + android:layout_centerHorizontal="true" + android:layout_marginBottom="8dp"/> + </RelativeLayout> + <RelativeLayout + android:id="@+id/accessible_answer_fragment_decline" + android:orientation="vertical" + android:layout_width="120dp" + android:layout_height="120dp" + android:focusable="true" + android:focusableInTouchMode="true" + android:clickable="true" + android:layout_alignParentLeft="true" + android:layout_centerVertical="true" + android:layout_marginLeft="16dp" + android:layout_marginRight="16dp"> + <ImageView + android:layout_width="64dp" + android:layout_height="64dp" + android:src="@drawable/ic_lockscreen_decline_activated_layer" + android:layout_centerInParent="true"> + </ImageView> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/description_target_decline" + android:textSize="12sp" + android:textColor="@color/accessible_answer_hint_text_color" + android:layout_alignParentBottom="true" + android:layout_centerHorizontal="true" + android:layout_marginBottom="8dp"/> + </RelativeLayout> + <LinearLayout + android:id="@+id/accessible_answer_fragment_text" + android:orientation="vertical" + android:layout_width="92dp" + android:layout_height="92dp" + android:focusable="true" + android:focusableInTouchMode="true" + android:clickable="true" + android:layout_alignParentEnd="false" + android:layout_alignParentStart="false" + android:layout_above="@+id/accessible_answer_fragment_decline" + android:layout_alignWithParentIfMissing="false" + android:layout_alignParentTop="false" + android:layout_alignParentLeft="false" + android:layout_alignParentBottom="false" + android:layout_alignParentRight="false" + android:layout_centerHorizontal="true" + android:contentDescription="@string/description_target_send_sms" + android:gravity="center"> + <ImageView + android:layout_width="64dp" + android:layout_height="64dp" + android:src="@drawable/ic_lockscreen_text"> + </ImageView> + </LinearLayout> + +</RelativeLayout>
\ No newline at end of file diff --git a/InCallUI/res/values/colors.xml b/InCallUI/res/values/colors.xml index 3697e11ba..60a017c21 100644 --- a/InCallUI/res/values/colors.xml +++ b/InCallUI/res/values/colors.xml @@ -73,11 +73,14 @@ <color name="glowpad_text_widget_ring_color">#ffffff</color> <color name="glowpad_widget_active_color">#ffffff</color> <color name="glowpad_text_widget_normal_tint">#cccccc</color> - <color name="glowpad_call_widget_normal_tint">@color/dialtacts_theme_color</color> + <color name="glowpad_call_widget_normal_tint">#00c853</color> <color name="glowpad_end_call_widget_normal_tint">#ff1744</color> <color name="glowpad_incoming_widget_tint">#a3a3a3</color> <color name="glowpad_incoming_widget_background_tint">#ffffff</color> + <!-- 70% opacity, white. --> + <color name="accessible_answer_hint_text_color">#B2FFFFFF</color> + <!-- 20% opacity, theme color. --> <color name="incall_dialpad_touch_tint">#330288d1</color> diff --git a/InCallUI/src/com/android/incallui/AccessibleAnswerFragment.java b/InCallUI/src/com/android/incallui/AccessibleAnswerFragment.java new file mode 100644 index 000000000..89c78ec61 --- /dev/null +++ b/InCallUI/src/com/android/incallui/AccessibleAnswerFragment.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2013 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; + +import android.os.Bundle; +import android.telecom.VideoProfile; +import android.view.GestureDetector; +import android.view.GestureDetector.SimpleOnGestureListener; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; + +import com.android.dialer.R; + +/** + * AnswerFragment to use when touch exploration is enabled in accessibility. + */ +public class AccessibleAnswerFragment extends AnswerFragment { + + private static final String TAG = AccessibleAnswerFragment.class.getSimpleName(); + private static final int SWIPE_THRESHOLD = 100; + + private View mAnswer; + private View mDecline; + private View mText; + + private TouchListener mTouchListener; + private GestureDetector mGestureDetector; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + ViewGroup group = (ViewGroup) inflater.inflate(R.layout.accessible_answer_fragment, + container, false); + + mTouchListener = new TouchListener(); + mGestureDetector = new GestureDetector(getContext(), new SimpleOnGestureListener() { + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, + float velocityY) { + return AccessibleAnswerFragment.this.onFling(e1, e2, velocityX, velocityX); + } + }); + + mAnswer = group.findViewById(R.id.accessible_answer_fragment_answer); + mAnswer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "Answer Button Clicked"); + onAnswer(VideoProfile.STATE_AUDIO_ONLY, getContext()); + } + }); + mDecline = group.findViewById(R.id.accessible_answer_fragment_decline); + mDecline.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "Decline Button Clicked"); + onDecline(getContext()); + } + }); + + mText = group.findViewById(R.id.accessible_answer_fragment_text); + mText.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "Text Button Clicked"); + onText(); + } + }); + return group; + } + + @Override + public void onResume() { + super.onResume(); + // Intercept all touch events for full screen swiping gesture. + InCallActivity activity = (InCallActivity) getActivity(); + activity.setDispatchTouchEventListener(mTouchListener); + } + + @Override + public void onPause() { + super.onPause(); + InCallActivity activity = (InCallActivity) getActivity(); + activity.setDispatchTouchEventListener(null); + } + + private class TouchListener implements View.OnTouchListener { + @Override + public boolean onTouch(View v, MotionEvent event) { + return mGestureDetector.onTouchEvent(event); + } + } + + private boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, + float velocityY) { + if (hasPendingDialogs()) { + return false; + } + + float diffY = e2.getY() - e1.getY(); + float diffX = e2.getX() - e1.getX(); + if (Math.abs(diffX) > Math.abs(diffY)) { + if (Math.abs(diffX) > SWIPE_THRESHOLD) { + if (diffX > 0) { + onSwipeRight(); + } else { + onSwipeLeft(); + } + } + return true; + } else if (Math.abs(diffY) > SWIPE_THRESHOLD) { + if (diffY > 0) { + onSwipeDown(); + } else { + onSwipeUp(); + } + return true; + } + + return false; + } + + private void onSwipeUp() { + Log.d(TAG, "onSwipeUp"); + onText(); + } + + private void onSwipeDown() { + Log.d(TAG, "onSwipeDown"); + } + + private void onSwipeLeft() { + Log.d(TAG, "onSwipeLeft"); + onDecline(getContext()); + } + + private void onSwipeRight() { + Log.d(TAG, "onSwipeRight"); + onAnswer(VideoProfile.STATE_AUDIO_ONLY, getContext()); + } +} diff --git a/InCallUI/src/com/android/incallui/AnswerFragment.java b/InCallUI/src/com/android/incallui/AnswerFragment.java index 7c67719b0..44ddfcd49 100644 --- a/InCallUI/src/com/android/incallui/AnswerFragment.java +++ b/InCallUI/src/com/android/incallui/AnswerFragment.java @@ -21,7 +21,6 @@ import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; -import android.telecom.VideoProfile; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; @@ -34,17 +33,17 @@ import android.widget.Button; import android.widget.EditText; import android.widget.ListView; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; +import com.android.dialer.R; import java.util.ArrayList; import java.util.List; + /** - * + * Provides only common interface and functions. Should be derived to implement the actual UI. */ -public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresenter.AnswerUi> - implements GlowPadWrapper.AnswerListener, AnswerPresenter.AnswerUi { +public abstract class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresenter.AnswerUi> + implements AnswerPresenter.AnswerUi { public static final int TARGET_SET_FOR_AUDIO_WITHOUT_SMS = 0; public static final int TARGET_SET_FOR_AUDIO_WITH_SMS = 1; @@ -53,6 +52,13 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente public static final int TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST = 4; /** + * This fragment implement no UI at all. Derived class should do it. + */ + @Override + public abstract View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState); + + /** * The popup showing the list of canned responses. * * This is an AlertDialog containing a ListView showing the possible choices. This may be null @@ -70,11 +76,6 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente private final List<String> mSmsResponses = new ArrayList<>(); - private GlowPadWrapper mGlowpad; - - public AnswerFragment() { - } - @Override public AnswerPresenter createPresenter() { return InCallPresenter.getInstance().getAnswerPresenter(); @@ -86,113 +87,6 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - mGlowpad = (GlowPadWrapper) inflater.inflate(R.layout.answer_fragment, - container, false); - - Log.d(this, "Creating view for answer fragment ", this); - Log.d(this, "Created from activity", getActivity()); - mGlowpad.setAnswerListener(this); - - return mGlowpad; - } - - @Override - public void onDestroyView() { - Log.d(this, "onDestroyView"); - if (mGlowpad != null) { - mGlowpad.stopPing(); - mGlowpad = null; - } - super.onDestroyView(); - } - - @Override - public void onShowAnswerUi(boolean shown) { - Log.d(this, "Show answer UI: " + shown); - if (shown) { - mGlowpad.startPing(); - } else { - mGlowpad.stopPing(); - } - } - - /** - * Sets targets on the glowpad according to target set identified by the parameter. - * @param targetSet Integer identifying the set of targets to use. - */ - public void showTargets(int targetSet) { - showTargets(targetSet, VideoProfile.STATE_BIDIRECTIONAL); - } - - /** - * Sets targets on the glowpad according to target set identified by the parameter. - * @param targetSet Integer identifying the set of targets to use. - */ - @Override - public void showTargets(int targetSet, int videoState) { - final int targetResourceId; - final int targetDescriptionsResourceId; - final int directionDescriptionsResourceId; - final int handleDrawableResourceId; - mGlowpad.setVideoState(videoState); - - switch (targetSet) { - case TARGET_SET_FOR_AUDIO_WITH_SMS: - targetResourceId = R.array.incoming_call_widget_audio_with_sms_targets; - targetDescriptionsResourceId = - R.array.incoming_call_widget_audio_with_sms_target_descriptions; - directionDescriptionsResourceId = - R.array.incoming_call_widget_audio_with_sms_direction_descriptions; - handleDrawableResourceId = R.drawable.ic_incall_audio_handle; - break; - case TARGET_SET_FOR_VIDEO_WITHOUT_SMS: - targetResourceId = R.array.incoming_call_widget_video_without_sms_targets; - targetDescriptionsResourceId = - R.array.incoming_call_widget_video_without_sms_target_descriptions; - directionDescriptionsResourceId = - R.array.incoming_call_widget_video_without_sms_direction_descriptions; - handleDrawableResourceId = R.drawable.ic_incall_video_handle; - break; - case TARGET_SET_FOR_VIDEO_WITH_SMS: - targetResourceId = R.array.incoming_call_widget_video_with_sms_targets; - targetDescriptionsResourceId = - R.array.incoming_call_widget_video_with_sms_target_descriptions; - directionDescriptionsResourceId = - R.array.incoming_call_widget_video_with_sms_direction_descriptions; - handleDrawableResourceId = R.drawable.ic_incall_video_handle; - break; - case TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST: - targetResourceId = - R.array.incoming_call_widget_video_request_targets; - targetDescriptionsResourceId = - R.array.incoming_call_widget_video_request_target_descriptions; - directionDescriptionsResourceId = R.array - .incoming_call_widget_video_request_target_direction_descriptions; - handleDrawableResourceId = R.drawable.ic_incall_video_handle; - break; - case TARGET_SET_FOR_AUDIO_WITHOUT_SMS: - default: - targetResourceId = R.array.incoming_call_widget_audio_without_sms_targets; - targetDescriptionsResourceId = - R.array.incoming_call_widget_audio_without_sms_target_descriptions; - directionDescriptionsResourceId = - R.array.incoming_call_widget_audio_without_sms_direction_descriptions; - handleDrawableResourceId = R.drawable.ic_incall_audio_handle; - break; - } - - if (targetResourceId != mGlowpad.getTargetResourceId()) { - mGlowpad.setTargetResources(targetResourceId); - mGlowpad.setTargetDescriptionsResourceId(targetDescriptionsResourceId); - mGlowpad.setDirectionDescriptionsResourceId(directionDescriptionsResourceId); - mGlowpad.setHandleDrawable(handleDrawableResourceId); - mGlowpad.reset(false); - } - } - - @Override public void showMessageDialog() { final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); @@ -207,9 +101,7 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialogInterface) { - if (mGlowpad != null) { - mGlowpad.startPing(); - } + onMessageDialogCancel(); dismissCannedResponsePopup(); getPresenter().onDismissDialog(); } @@ -239,7 +131,7 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente * This is safe to call even if the popup is already dismissed, and even if you never called * showRespondViaSmsPopup() in the first place. */ - private void dismissCannedResponsePopup() { + protected void dismissCannedResponsePopup() { if (mCannedResponsePopup != null) { mCannedResponsePopup.dismiss(); // safe even if already dismissed mCannedResponsePopup = null; @@ -250,10 +142,10 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente * Dismiss the custom compose message popup. */ private void dismissCustomMessagePopup() { - if (mCustomMessagePopup != null) { - mCustomMessagePopup.dismiss(); - mCustomMessagePopup = null; - } + if (mCustomMessagePopup != null) { + mCustomMessagePopup.dismiss(); + mCustomMessagePopup = null; + } } public void dismissPendingDialogs() { @@ -280,23 +172,23 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente builder.setCancelable(true).setView(et) .setPositiveButton(R.string.custom_message_send, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // The order is arranged in a way that the popup will be destroyed when the - // InCallActivity is about to finish. - final String textMessage = et.getText().toString().trim(); - dismissCustomMessagePopup(); - getPresenter().rejectCallWithMessage(textMessage); - } - }) + @Override + public void onClick(DialogInterface dialog, int which) { + // The order is arranged in a way that the popup will be destroyed + // when the InCallActivity is about to finish. + final String textMessage = et.getText().toString().trim(); + dismissCustomMessagePopup(); + getPresenter().rejectCallWithMessage(textMessage); + } + }) .setNegativeButton(R.string.custom_message_cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dismissCustomMessagePopup(); - getPresenter().onDismissDialog(); - } - }) + @Override + public void onClick(DialogInterface dialog, int which) { + dismissCustomMessagePopup(); + getPresenter().onDismissDialog(); + } + }) .setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialogInterface) { @@ -352,23 +244,19 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente return getActivity(); } - @Override public void onAnswer(int videoState, Context context) { Log.d(this, "onAnswer videoState=" + videoState + " context=" + context); getPresenter().onAnswer(videoState, context); } - @Override public void onDecline(Context context) { getPresenter().onDecline(context); } - @Override public void onDeclineUpgradeRequest(Context context) { InCallPresenter.getInstance().declineUpgradeRequest(context); } - @Override public void onText() { getPresenter().onText(); } @@ -400,4 +288,20 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente } } } + + public void onShowAnswerUi(boolean shown) { + // Do Nothing + } + + public void showTargets(int targetSet) { + // Do Nothing + } + + public void showTargets(int targetSet, int videoState) { + // Do Nothing + } + + protected void onMessageDialogCancel() { + // Do nothing. + } } diff --git a/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java b/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java new file mode 100644 index 000000000..62a8e7829 --- /dev/null +++ b/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2013 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; + +import android.os.Bundle; +import android.telecom.VideoProfile; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.android.dialer.R; + +public class GlowPadAnswerFragment extends AnswerFragment { + + private GlowPadWrapper mGlowpad; + + public GlowPadAnswerFragment() { + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + mGlowpad = (GlowPadWrapper) inflater.inflate(R.layout.answer_fragment, + container, false); + + Log.d(this, "Creating view for answer fragment ", this); + Log.d(this, "Created from activity", getActivity()); + mGlowpad.setAnswerFragment(this); + + return mGlowpad; + } + + @Override + public void onResume() { + super.onResume(); + mGlowpad.requestFocus(); + } + + @Override + public void onDestroyView() { + Log.d(this, "onDestroyView"); + if (mGlowpad != null) { + mGlowpad.stopPing(); + mGlowpad = null; + } + super.onDestroyView(); + } + + @Override + public void onShowAnswerUi(boolean shown) { + Log.d(this, "Show answer UI: " + shown); + if (shown) { + mGlowpad.startPing(); + } else { + mGlowpad.stopPing(); + } + } + + /** + * Sets targets on the glowpad according to target set identified by the parameter. + * + * @param targetSet Integer identifying the set of targets to use. + */ + public void showTargets(int targetSet) { + showTargets(targetSet, VideoProfile.STATE_BIDIRECTIONAL); + } + + /** + * Sets targets on the glowpad according to target set identified by the parameter. + * + * @param targetSet Integer identifying the set of targets to use. + */ + @Override + public void showTargets(int targetSet, int videoState) { + final int targetResourceId; + final int targetDescriptionsResourceId; + final int directionDescriptionsResourceId; + final int handleDrawableResourceId; + mGlowpad.setVideoState(videoState); + + switch (targetSet) { + case TARGET_SET_FOR_AUDIO_WITH_SMS: + targetResourceId = R.array.incoming_call_widget_audio_with_sms_targets; + targetDescriptionsResourceId = + R.array.incoming_call_widget_audio_with_sms_target_descriptions; + directionDescriptionsResourceId = + R.array.incoming_call_widget_audio_with_sms_direction_descriptions; + handleDrawableResourceId = R.drawable.ic_incall_audio_handle; + break; + case TARGET_SET_FOR_VIDEO_WITHOUT_SMS: + targetResourceId = R.array.incoming_call_widget_video_without_sms_targets; + targetDescriptionsResourceId = + R.array.incoming_call_widget_video_without_sms_target_descriptions; + directionDescriptionsResourceId = + R.array.incoming_call_widget_video_without_sms_direction_descriptions; + handleDrawableResourceId = R.drawable.ic_incall_video_handle; + break; + case TARGET_SET_FOR_VIDEO_WITH_SMS: + targetResourceId = R.array.incoming_call_widget_video_with_sms_targets; + targetDescriptionsResourceId = + R.array.incoming_call_widget_video_with_sms_target_descriptions; + directionDescriptionsResourceId = + R.array.incoming_call_widget_video_with_sms_direction_descriptions; + handleDrawableResourceId = R.drawable.ic_incall_video_handle; + break; + case TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST: + targetResourceId = + R.array.incoming_call_widget_video_request_targets; + targetDescriptionsResourceId = + R.array.incoming_call_widget_video_request_target_descriptions; + directionDescriptionsResourceId = R.array + .incoming_call_widget_video_request_target_direction_descriptions; + handleDrawableResourceId = R.drawable.ic_incall_video_handle; + break; + case TARGET_SET_FOR_AUDIO_WITHOUT_SMS: + default: + targetResourceId = R.array.incoming_call_widget_audio_without_sms_targets; + targetDescriptionsResourceId = + R.array.incoming_call_widget_audio_without_sms_target_descriptions; + directionDescriptionsResourceId = + R.array.incoming_call_widget_audio_without_sms_direction_descriptions; + handleDrawableResourceId = R.drawable.ic_incall_audio_handle; + break; + } + + if (targetResourceId != mGlowpad.getTargetResourceId()) { + mGlowpad.setTargetResources(targetResourceId); + mGlowpad.setTargetDescriptionsResourceId(targetDescriptionsResourceId); + mGlowpad.setDirectionDescriptionsResourceId(directionDescriptionsResourceId); + mGlowpad.setHandleDrawable(handleDrawableResourceId); + mGlowpad.reset(false); + } + } + + @Override + protected void onMessageDialogCancel() { + if (mGlowpad != null) { + mGlowpad.startPing(); + } + } +} diff --git a/InCallUI/src/com/android/incallui/GlowPadWrapper.java b/InCallUI/src/com/android/incallui/GlowPadWrapper.java index ea5fc9223..1bd6d3919 100644 --- a/InCallUI/src/com/android/incallui/GlowPadWrapper.java +++ b/InCallUI/src/com/android/incallui/GlowPadWrapper.java @@ -46,7 +46,7 @@ public class GlowPadWrapper extends GlowPadView implements GlowPadView.OnTrigger } }; - private AnswerListener mAnswerListener; + private AnswerFragment mAnswerFragment; private boolean mPingEnabled = true; private boolean mTargetTriggered = false; private int mVideoState = VideoProfile.STATE_BIDIRECTIONAL; @@ -113,24 +113,24 @@ public class GlowPadWrapper extends GlowPadView implements GlowPadView.OnTrigger final int resId = getResourceIdForTarget(target); switch (resId) { case R.drawable.ic_lockscreen_answer: - mAnswerListener.onAnswer(VideoProfile.STATE_AUDIO_ONLY, getContext()); + mAnswerFragment.onAnswer(VideoProfile.STATE_AUDIO_ONLY, getContext()); mTargetTriggered = true; break; case R.drawable.ic_lockscreen_decline: - mAnswerListener.onDecline(getContext()); + mAnswerFragment.onDecline(getContext()); mTargetTriggered = true; break; case R.drawable.ic_lockscreen_text: - mAnswerListener.onText(); + mAnswerFragment.onText(); mTargetTriggered = true; break; case R.drawable.ic_videocam: case R.drawable.ic_lockscreen_answer_video: - mAnswerListener.onAnswer(mVideoState, getContext()); + mAnswerFragment.onAnswer(mVideoState, getContext()); mTargetTriggered = true; break; case R.drawable.ic_lockscreen_decline_video: - mAnswerListener.onDeclineUpgradeRequest(getContext()); + mAnswerFragment.onDeclineUpgradeRequest(getContext()); mTargetTriggered = true; break; default: @@ -149,8 +149,8 @@ public class GlowPadWrapper extends GlowPadView implements GlowPadView.OnTrigger } - public void setAnswerListener(AnswerListener listener) { - mAnswerListener = listener; + public void setAnswerFragment(AnswerFragment fragment) { + mAnswerFragment = fragment; } /** @@ -161,11 +161,4 @@ public class GlowPadWrapper extends GlowPadView implements GlowPadView.OnTrigger public void setVideoState(int videoState) { mVideoState = videoState; } - - public interface AnswerListener { - void onAnswer(int videoState, Context context); - void onDecline(Context context); - void onDeclineUpgradeRequest(Context context); - void onText(); - } } diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java index 7b53ed7cd..cbcf50c41 100644 --- a/InCallUI/src/com/android/incallui/InCallActivity.java +++ b/InCallUI/src/com/android/incallui/InCallActivity.java @@ -26,8 +26,8 @@ import android.app.FragmentManager; import android.app.FragmentTransaction; import android.content.Context; import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnCancelListener; +import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.res.Configuration; import android.graphics.Point; @@ -37,20 +37,19 @@ import android.os.Trace; import android.telecom.DisconnectCause; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; -import android.view.Display; +import android.view.KeyEvent; import android.view.MenuItem; +import android.view.MotionEvent; import android.view.OrientationEventListener; import android.view.Surface; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.view.KeyEvent; import android.view.View; +import android.view.View.OnTouchListener; import android.view.Window; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; -import com.android.phone.common.animation.AnimUtils; -import com.android.phone.common.animation.AnimationListenerAdapter; import com.android.contacts.common.activity.TransactionSafeActivity; import com.android.contacts.common.interactions.TouchPointManager; import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment; @@ -58,6 +57,9 @@ import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment.Selec import com.android.dialer.logging.Logger; import com.android.dialer.logging.ScreenEvent; import com.android.incallui.Call.State; +import com.android.incallui.util.AccessibilityUtil; +import com.android.phone.common.animation.AnimUtils; +import com.android.phone.common.animation.AnimationListenerAdapter; import java.util.ArrayList; import java.util.List; @@ -123,6 +125,8 @@ public class InCallActivity extends TransactionSafeActivity implements FragmentD } }; + private OnTouchListener mDispatchTouchEventListener; + private SelectPhoneAccountListener mSelectAcctListener = new SelectPhoneAccountListener() { @Override public void onPhoneAccountSelected(PhoneAccountHandle selectedAccountHandle, @@ -461,6 +465,17 @@ public class InCallActivity extends TransactionSafeActivity implements FragmentD } @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + if (mDispatchTouchEventListener != null) { + boolean handled = mDispatchTouchEventListener.onTouch(null, ev); + if (handled) { + return true; + } + } + return super.dispatchTouchEvent(ev); + } + + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_CALL: @@ -513,7 +528,6 @@ public class InCallActivity extends TransactionSafeActivity implements FragmentD if (event.getRepeatCount() == 0 && handleDialerKeyDown(keyCode, event)) { return true; } - return super.onKeyDown(keyCode, event); } @@ -714,7 +728,11 @@ public class InCallActivity extends TransactionSafeActivity implements FragmentD mDialpadFragment = new DialpadFragment(); return mDialpadFragment; } else if (TAG_ANSWER_FRAGMENT.equals(tag)) { - mAnswerFragment = new AnswerFragment(); + if (AccessibilityUtil.isTalkBackEnabled(this)) { + mAnswerFragment = new AccessibleAnswerFragment(); + } else { + mAnswerFragment = new GlowPadAnswerFragment(); + } return mAnswerFragment; } else if (TAG_CONFERENCE_FRAGMENT.equals(tag)) { mConferenceManagerFragment = new ConferenceManagerFragment(); @@ -914,4 +932,13 @@ public class InCallActivity extends TransactionSafeActivity implements FragmentD } } } + + + public OnTouchListener getDispatchTouchEventListener() { + return mDispatchTouchEventListener; + } + + public void setDispatchTouchEventListener(OnTouchListener mDispatchTouchEventListener) { + this.mDispatchTouchEventListener = mDispatchTouchEventListener; + } } diff --git a/InCallUI/src/com/android/incallui/util/AccessibilityUtil.java b/InCallUI/src/com/android/incallui/util/AccessibilityUtil.java new file mode 100644 index 000000000..1fdd2bac6 --- /dev/null +++ b/InCallUI/src/com/android/incallui/util/AccessibilityUtil.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2013 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.util; + +import android.content.Context; +import android.view.accessibility.AccessibilityManager; + +public class AccessibilityUtil { + public static boolean isTalkBackEnabled(Context context) { + AccessibilityManager accessibilityManager = (AccessibilityManager) context + .getSystemService(Context.ACCESSIBILITY_SERVICE); + return accessibilityManager != null + && accessibilityManager.isEnabled() + && accessibilityManager.isTouchExplorationEnabled(); + } +} |