summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTa-wei Yen <twyen@google.com>2015-11-16 19:06:49 +0000
committerandroid-build-merger <android-build-merger@google.com>2015-11-16 19:06:49 +0000
commitaae598cb8daac3add71a2ab6e8df85972706ea95 (patch)
tree10d03629cc44c1200437a465e5b8541c8a137410
parent0642dfeadfc31b2c84b62bbddfd00c53fccda4b6 (diff)
parentd21b8fdefc3279a9c1b424d2c710e8768eee4cbe (diff)
Merge "Use separate AnswerFragment for Talkback" into ub-contactsdialer-a-dev
am: 7e5e6be79a * commit '7e5e6be79a7e4a22139bdfbb1052dc48d28631f8': Use separate AnswerFragment for Talkback
-rw-r--r--InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml2
-rw-r--r--InCallUI/res/layout/accessible_answer_fragment.xml104
-rw-r--r--InCallUI/res/values/colors.xml5
-rw-r--r--InCallUI/src/com/android/incallui/AccessibleAnswerFragment.java157
-rw-r--r--InCallUI/src/com/android/incallui/AnswerFragment.java194
-rw-r--r--InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java155
-rw-r--r--InCallUI/src/com/android/incallui/GlowPadWrapper.java23
-rw-r--r--InCallUI/src/com/android/incallui/InCallActivity.java45
-rw-r--r--InCallUI/src/com/android/incallui/util/AccessibilityUtil.java30
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();
+ }
+}