diff options
47 files changed, 549 insertions, 24 deletions
diff --git a/InCallUI/res/drawable-hdpi/dial_num_0_no_plus_wht.png b/InCallUI/res/drawable-hdpi/dial_num_0_no_plus_wht.png Binary files differnew file mode 100644 index 000000000..69849eca3 --- /dev/null +++ b/InCallUI/res/drawable-hdpi/dial_num_0_no_plus_wht.png diff --git a/InCallUI/res/drawable-hdpi/dial_num_1_no_vm_wht.png b/InCallUI/res/drawable-hdpi/dial_num_1_no_vm_wht.png Binary files differnew file mode 100644 index 000000000..af7ec4296 --- /dev/null +++ b/InCallUI/res/drawable-hdpi/dial_num_1_no_vm_wht.png diff --git a/InCallUI/res/drawable-hdpi/dial_num_2_wht.png b/InCallUI/res/drawable-hdpi/dial_num_2_wht.png Binary files differnew file mode 100644 index 000000000..2ae20ab39 --- /dev/null +++ b/InCallUI/res/drawable-hdpi/dial_num_2_wht.png diff --git a/InCallUI/res/drawable-hdpi/dial_num_3_wht.png b/InCallUI/res/drawable-hdpi/dial_num_3_wht.png Binary files differnew file mode 100644 index 000000000..991d5f3dc --- /dev/null +++ b/InCallUI/res/drawable-hdpi/dial_num_3_wht.png diff --git a/InCallUI/res/drawable-hdpi/dial_num_4_wht.png b/InCallUI/res/drawable-hdpi/dial_num_4_wht.png Binary files differnew file mode 100644 index 000000000..7aad3ef97 --- /dev/null +++ b/InCallUI/res/drawable-hdpi/dial_num_4_wht.png diff --git a/InCallUI/res/drawable-hdpi/dial_num_5_wht.png b/InCallUI/res/drawable-hdpi/dial_num_5_wht.png Binary files differnew file mode 100644 index 000000000..42a1d0bb5 --- /dev/null +++ b/InCallUI/res/drawable-hdpi/dial_num_5_wht.png diff --git a/InCallUI/res/drawable-hdpi/dial_num_6_wht.png b/InCallUI/res/drawable-hdpi/dial_num_6_wht.png Binary files differnew file mode 100644 index 000000000..b03e0191a --- /dev/null +++ b/InCallUI/res/drawable-hdpi/dial_num_6_wht.png diff --git a/InCallUI/res/drawable-hdpi/dial_num_7_wht.png b/InCallUI/res/drawable-hdpi/dial_num_7_wht.png Binary files differnew file mode 100644 index 000000000..8b72fffd6 --- /dev/null +++ b/InCallUI/res/drawable-hdpi/dial_num_7_wht.png diff --git a/InCallUI/res/drawable-hdpi/dial_num_8_wht.png b/InCallUI/res/drawable-hdpi/dial_num_8_wht.png Binary files differnew file mode 100644 index 000000000..822f21a94 --- /dev/null +++ b/InCallUI/res/drawable-hdpi/dial_num_8_wht.png diff --git a/InCallUI/res/drawable-hdpi/dial_num_9_wht.png b/InCallUI/res/drawable-hdpi/dial_num_9_wht.png Binary files differnew file mode 100644 index 000000000..2ee944b5d --- /dev/null +++ b/InCallUI/res/drawable-hdpi/dial_num_9_wht.png diff --git a/InCallUI/res/drawable-hdpi/dial_num_pound_wht.png b/InCallUI/res/drawable-hdpi/dial_num_pound_wht.png Binary files differnew file mode 100644 index 000000000..e10e57d5b --- /dev/null +++ b/InCallUI/res/drawable-hdpi/dial_num_pound_wht.png diff --git a/InCallUI/res/drawable-hdpi/dial_num_star_wht.png b/InCallUI/res/drawable-hdpi/dial_num_star_wht.png Binary files differnew file mode 100644 index 000000000..1dfc111e7 --- /dev/null +++ b/InCallUI/res/drawable-hdpi/dial_num_star_wht.png diff --git a/InCallUI/res/drawable-mdpi/dial_num_0_no_plus_wht.png b/InCallUI/res/drawable-mdpi/dial_num_0_no_plus_wht.png Binary files differnew file mode 100644 index 000000000..1d8b0e3e2 --- /dev/null +++ b/InCallUI/res/drawable-mdpi/dial_num_0_no_plus_wht.png diff --git a/InCallUI/res/drawable-mdpi/dial_num_1_no_vm_wht.png b/InCallUI/res/drawable-mdpi/dial_num_1_no_vm_wht.png Binary files differnew file mode 100644 index 000000000..e253724d6 --- /dev/null +++ b/InCallUI/res/drawable-mdpi/dial_num_1_no_vm_wht.png diff --git a/InCallUI/res/drawable-mdpi/dial_num_2_wht.png b/InCallUI/res/drawable-mdpi/dial_num_2_wht.png Binary files differnew file mode 100644 index 000000000..e311f4f64 --- /dev/null +++ b/InCallUI/res/drawable-mdpi/dial_num_2_wht.png diff --git a/InCallUI/res/drawable-mdpi/dial_num_3_wht.png b/InCallUI/res/drawable-mdpi/dial_num_3_wht.png Binary files differnew file mode 100644 index 000000000..f07324a38 --- /dev/null +++ b/InCallUI/res/drawable-mdpi/dial_num_3_wht.png diff --git a/InCallUI/res/drawable-mdpi/dial_num_4_wht.png b/InCallUI/res/drawable-mdpi/dial_num_4_wht.png Binary files differnew file mode 100644 index 000000000..cd8d33c89 --- /dev/null +++ b/InCallUI/res/drawable-mdpi/dial_num_4_wht.png diff --git a/InCallUI/res/drawable-mdpi/dial_num_5_wht.png b/InCallUI/res/drawable-mdpi/dial_num_5_wht.png Binary files differnew file mode 100644 index 000000000..a9f27dc3a --- /dev/null +++ b/InCallUI/res/drawable-mdpi/dial_num_5_wht.png diff --git a/InCallUI/res/drawable-mdpi/dial_num_6_wht.png b/InCallUI/res/drawable-mdpi/dial_num_6_wht.png Binary files differnew file mode 100644 index 000000000..2bdf08e51 --- /dev/null +++ b/InCallUI/res/drawable-mdpi/dial_num_6_wht.png diff --git a/InCallUI/res/drawable-mdpi/dial_num_7_wht.png b/InCallUI/res/drawable-mdpi/dial_num_7_wht.png Binary files differnew file mode 100644 index 000000000..6c1c599a5 --- /dev/null +++ b/InCallUI/res/drawable-mdpi/dial_num_7_wht.png diff --git a/InCallUI/res/drawable-mdpi/dial_num_8_wht.png b/InCallUI/res/drawable-mdpi/dial_num_8_wht.png Binary files differnew file mode 100644 index 000000000..db0694ce1 --- /dev/null +++ b/InCallUI/res/drawable-mdpi/dial_num_8_wht.png diff --git a/InCallUI/res/drawable-mdpi/dial_num_9_wht.png b/InCallUI/res/drawable-mdpi/dial_num_9_wht.png Binary files differnew file mode 100644 index 000000000..692fdb06e --- /dev/null +++ b/InCallUI/res/drawable-mdpi/dial_num_9_wht.png diff --git a/InCallUI/res/drawable-mdpi/dial_num_pound_wht.png b/InCallUI/res/drawable-mdpi/dial_num_pound_wht.png Binary files differnew file mode 100644 index 000000000..f216d0502 --- /dev/null +++ b/InCallUI/res/drawable-mdpi/dial_num_pound_wht.png diff --git a/InCallUI/res/drawable-mdpi/dial_num_star_wht.png b/InCallUI/res/drawable-mdpi/dial_num_star_wht.png Binary files differnew file mode 100644 index 000000000..f7e8e9f73 --- /dev/null +++ b/InCallUI/res/drawable-mdpi/dial_num_star_wht.png diff --git a/InCallUI/res/drawable-xhdpi/dial_num_0_no_plus_wht.png b/InCallUI/res/drawable-xhdpi/dial_num_0_no_plus_wht.png Binary files differnew file mode 100644 index 000000000..11ca993c1 --- /dev/null +++ b/InCallUI/res/drawable-xhdpi/dial_num_0_no_plus_wht.png diff --git a/InCallUI/res/drawable-xhdpi/dial_num_1_no_vm_wht.png b/InCallUI/res/drawable-xhdpi/dial_num_1_no_vm_wht.png Binary files differnew file mode 100644 index 000000000..8d2ac70ae --- /dev/null +++ b/InCallUI/res/drawable-xhdpi/dial_num_1_no_vm_wht.png diff --git a/InCallUI/res/drawable-xhdpi/dial_num_2_wht.png b/InCallUI/res/drawable-xhdpi/dial_num_2_wht.png Binary files differnew file mode 100644 index 000000000..12c4ab9ba --- /dev/null +++ b/InCallUI/res/drawable-xhdpi/dial_num_2_wht.png diff --git a/InCallUI/res/drawable-xhdpi/dial_num_3_wht.png b/InCallUI/res/drawable-xhdpi/dial_num_3_wht.png Binary files differnew file mode 100644 index 000000000..4353e8a39 --- /dev/null +++ b/InCallUI/res/drawable-xhdpi/dial_num_3_wht.png diff --git a/InCallUI/res/drawable-xhdpi/dial_num_4_wht.png b/InCallUI/res/drawable-xhdpi/dial_num_4_wht.png Binary files differnew file mode 100644 index 000000000..ccee5cce7 --- /dev/null +++ b/InCallUI/res/drawable-xhdpi/dial_num_4_wht.png diff --git a/InCallUI/res/drawable-xhdpi/dial_num_5_wht.png b/InCallUI/res/drawable-xhdpi/dial_num_5_wht.png Binary files differnew file mode 100644 index 000000000..f27f153cd --- /dev/null +++ b/InCallUI/res/drawable-xhdpi/dial_num_5_wht.png diff --git a/InCallUI/res/drawable-xhdpi/dial_num_6_wht.png b/InCallUI/res/drawable-xhdpi/dial_num_6_wht.png Binary files differnew file mode 100644 index 000000000..8966d13d3 --- /dev/null +++ b/InCallUI/res/drawable-xhdpi/dial_num_6_wht.png diff --git a/InCallUI/res/drawable-xhdpi/dial_num_7_wht.png b/InCallUI/res/drawable-xhdpi/dial_num_7_wht.png Binary files differnew file mode 100644 index 000000000..b01881058 --- /dev/null +++ b/InCallUI/res/drawable-xhdpi/dial_num_7_wht.png diff --git a/InCallUI/res/drawable-xhdpi/dial_num_8_wht.png b/InCallUI/res/drawable-xhdpi/dial_num_8_wht.png Binary files differnew file mode 100644 index 000000000..7c7b4f8db --- /dev/null +++ b/InCallUI/res/drawable-xhdpi/dial_num_8_wht.png diff --git a/InCallUI/res/drawable-xhdpi/dial_num_9_wht.png b/InCallUI/res/drawable-xhdpi/dial_num_9_wht.png Binary files differnew file mode 100644 index 000000000..23984f03d --- /dev/null +++ b/InCallUI/res/drawable-xhdpi/dial_num_9_wht.png diff --git a/InCallUI/res/drawable-xhdpi/dial_num_pound_wht.png b/InCallUI/res/drawable-xhdpi/dial_num_pound_wht.png Binary files differnew file mode 100644 index 000000000..be21af8d8 --- /dev/null +++ b/InCallUI/res/drawable-xhdpi/dial_num_pound_wht.png diff --git a/InCallUI/res/drawable-xhdpi/dial_num_star_wht.png b/InCallUI/res/drawable-xhdpi/dial_num_star_wht.png Binary files differnew file mode 100644 index 000000000..061a4946f --- /dev/null +++ b/InCallUI/res/drawable-xhdpi/dial_num_star_wht.png diff --git a/InCallUI/res/layout/dtmf_twelve_key_dialer_view.xml b/InCallUI/res/layout/dtmf_twelve_key_dialer_view.xml new file mode 100644 index 000000000..c4fecf358 --- /dev/null +++ b/InCallUI/res/layout/dtmf_twelve_key_dialer_view.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2006 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. +--> + +<!-- The grid of buttons used in the onscreen DTMF dialpad; + see dtmf_twelve_key_dialer_view.xml. --> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/dtmf_twelve_key_dialer_view" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:layout_marginTop="1dip" > + + <!-- Display of the digits you've typed so far. + This widget appears completely non-interactive to the user: you + can't edit or "hit backspace" since these are DTMF tones you've + already sent over the network. But it's still an EditText rather + than a TextView because it needs to receive key events from a + hard keyboard, if present (see mDialerKeyListener). --> + <EditText + android:id="@+id/dtmfDialerField" + android:layout_width="match_parent" + android:layout_height="32dp" + android:layout_marginTop="10dp" + android:layout_marginBottom="5dp" + android:layout_marginStart="32dp" + android:layout_marginEnd="32dp" + android:paddingEnd="16dp" + android:paddingStart="16dp" + android:singleLine="true" + android:scrollHorizontally="true" + android:textSize="24sp" + android:gravity="center" + android:freezesText="true" + android:background="@null" + android:textColor="@color/dtmf_dialer_display_text" + android:focusableInTouchMode="false" + android:clickable="false"/> + + <TableLayout + android:id="@+id/dialpad" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_weight="@integer/dialpad_layout_weight_dialpad" + android:layout_gravity="center_horizontal" + android:layout_marginTop="@dimen/dialpad_vertical_margin" + android:paddingStart="5dip" + android:paddingEnd="5dip" + android:paddingBottom="10dip" + android:background="@drawable/dialpad_background" + android:layoutDirection="ltr"> + + <TableRow + android:layout_height="0px" + android:layout_weight="1"> + <ImageButton android:id="@+id/one" style="@style/DialpadButtonStyle" + android:src="@drawable/dial_num_1_no_vm_wht" + android:contentDescription="@string/description_image_button_one" /> + <ImageButton android:id="@+id/two" style="@style/DialpadButtonStyle" + android:src="@drawable/dial_num_2_wht" + android:contentDescription="@string/description_image_button_two" /> + <ImageButton android:id="@+id/three" style="@style/DialpadButtonStyle" + android:src="@drawable/dial_num_3_wht" + android:contentDescription="@string/description_image_button_three" /> + </TableRow> + + <TableRow + android:layout_height="0px" + android:layout_weight="1"> + <ImageButton android:id="@+id/four" style="@style/DialpadButtonStyle" + android:src="@drawable/dial_num_4_wht" + android:contentDescription="@string/description_image_button_four" /> + <ImageButton android:id="@+id/five" style="@style/DialpadButtonStyle" + android:src="@drawable/dial_num_5_wht" + android:contentDescription="@string/description_image_button_five" /> + <ImageButton android:id="@+id/six" style="@style/DialpadButtonStyle" + android:src="@drawable/dial_num_6_wht" + android:contentDescription="@string/description_image_button_six" /> + </TableRow> + + <TableRow + android:layout_height="0px" + android:layout_weight="1"> + <ImageButton android:id="@+id/seven" style="@style/DialpadButtonStyle" + android:src="@drawable/dial_num_7_wht" + android:contentDescription="@string/description_image_button_seven" /> + <ImageButton android:id="@+id/eight" style="@style/DialpadButtonStyle" + android:src="@drawable/dial_num_8_wht" + android:contentDescription="@string/description_image_button_eight" /> + <ImageButton android:id="@+id/nine" style="@style/DialpadButtonStyle" + android:src="@drawable/dial_num_9_wht" + android:contentDescription="@string/description_image_button_nine" /> + </TableRow> + + <TableRow + android:layout_height="0px" + android:layout_weight="1"> + <ImageButton android:id="@+id/star" style="@style/DialpadButtonStyle" + android:src="@drawable/dial_num_star_wht" + android:contentDescription="@string/description_image_button_star" /> + <ImageButton android:id="@+id/zero" style="@style/DialpadButtonStyle" + android:src="@drawable/dial_num_0_no_plus_wht" + android:contentDescription="@string/description_image_button_zero" /> + <ImageButton android:id="@+id/pound" style="@style/DialpadButtonStyle" + android:src="@drawable/dial_num_pound_wht" + android:contentDescription="@string/description_image_button_pound" /> + </TableRow> + </TableLayout> +</LinearLayout> diff --git a/InCallUI/res/layout/incall_screen.xml b/InCallUI/res/layout/incall_screen.xml index 9c364ed5c..25241baca 100644 --- a/InCallUI/res/layout/incall_screen.xml +++ b/InCallUI/res/layout/incall_screen.xml @@ -15,21 +15,39 @@ --> <!-- In-call Phone UI; see InCallActivity.java. --> -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:id="@+id/main"> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/main"> - <LinearLayout android:id="@+id/in_call_and_button_container" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> + <LinearLayout + android:id="@+id/in_call_and_button_container" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> - <fragment android:name="com.android.incallui.CallCardFragment" - android:id="@+id/callCardFragment" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1"/> + <RelativeLayout + android:id="@+id/in_call_card_container" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1"> + + <fragment + android:name="com.android.incallui.CallCardFragment" + android:id="@+id/callCardFragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_alignParentTop="true" + android:layout_alignParentStart="true" /> + <fragment + android:name="com.android.incallui.DialpadFragment" + android:id="@+id/dialpadFragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_alignParentTop="true" + android:layout_alignParentStart="true" /> + </RelativeLayout> <fragment android:name="com.android.incallui.CallButtonFragment" android:id="@+id/callButtonFragment" diff --git a/InCallUI/src/com/android/incallui/AnswerFragment.java b/InCallUI/src/com/android/incallui/AnswerFragment.java index 0995ed665..a20fdb9ab 100644 --- a/InCallUI/src/com/android/incallui/AnswerFragment.java +++ b/InCallUI/src/com/android/incallui/AnswerFragment.java @@ -16,10 +16,6 @@ package com.android.incallui; -import com.google.common.base.Preconditions; - -import android.app.Fragment; -import android.app.FragmentTransaction; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -53,7 +49,7 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter> implements @Override public void showAnswerUi(boolean show) { - getView().setVisibility(show ? View.VISIBLE : View.INVISIBLE); + getView().setVisibility(show ? View.VISIBLE : View.GONE); } @Override diff --git a/InCallUI/src/com/android/incallui/CallButtonFragment.java b/InCallUI/src/com/android/incallui/CallButtonFragment.java index 3ccc1d1d1..772251dfa 100644 --- a/InCallUI/src/com/android/incallui/CallButtonFragment.java +++ b/InCallUI/src/com/android/incallui/CallButtonFragment.java @@ -34,6 +34,8 @@ public class CallButtonFragment extends BaseFragment<CallButtonPresenter> private ToggleButton mMuteButton; private ToggleButton mAudioButton; private ToggleButton mHoldButton; + private ToggleButton mShowDialpadButton; + private View mEndCallButton; @Override @@ -87,6 +89,14 @@ public class CallButtonFragment extends BaseFragment<CallButtonPresenter> } }); + mShowDialpadButton = (ToggleButton) parent.findViewById(R.id.dialpadButton); + mShowDialpadButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + getPresenter().showDialpadClicked(isChecked); + } + }); + return parent; } @@ -121,4 +131,12 @@ public class CallButtonFragment extends BaseFragment<CallButtonPresenter> public void setHold(boolean value) { mHoldButton.setChecked(value); } + + @Override + public void displayDialpad(boolean value) { + mShowDialpadButton.setChecked(value); + if (getActivity() != null && getActivity() instanceof InCallActivity) { + ((InCallActivity) getActivity()).displayDialpad(value); + } + } } diff --git a/InCallUI/src/com/android/incallui/CallButtonPresenter.java b/InCallUI/src/com/android/incallui/CallButtonPresenter.java index 60ab7bbf4..35e6ab7f6 100644 --- a/InCallUI/src/com/android/incallui/CallButtonPresenter.java +++ b/InCallUI/src/com/android/incallui/CallButtonPresenter.java @@ -98,10 +98,16 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto getUi().setHold(checked); } + public void showDialpadClicked(boolean checked) { + Logger.v(this, "Show dialpad " + String.valueOf(checked)); + getUi().displayDialpad(checked); + } + public interface CallButtonUi extends Ui { void setVisible(boolean on); void setMute(boolean on); void setSpeaker(boolean on); void setHold(boolean on); + void displayDialpad(boolean on); } } diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java index 3f46bb568..76bdd1157 100644 --- a/InCallUI/src/com/android/incallui/CallCardFragment.java +++ b/InCallUI/src/com/android/incallui/CallCardFragment.java @@ -56,6 +56,15 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter> } @Override + public void setVisible(boolean on) { + if (on) { + getView().setVisibility(View.VISIBLE); + } else { + getView().setVisibility(View.INVISIBLE); + } + } + + @Override public void setSecondaryCallInfo(boolean show, String number) { if (show) { showAndInitializeSecondaryCallInfo(); diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java index 04a43eae1..bea89ef8e 100644 --- a/InCallUI/src/com/android/incallui/CallCardPresenter.java +++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java @@ -72,8 +72,9 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi> public interface CallCardUi extends Ui { // TODO(klp): Consider passing in the Call object directly in these methods. - public void setNumber(String number); - public void setName(String name); - public void setSecondaryCallInfo(boolean show, String number); + void setVisible(boolean on); + void setNumber(String number); + void setName(String name); + void setSecondaryCallInfo(boolean show, String number); } } diff --git a/InCallUI/src/com/android/incallui/CallCommandClient.java b/InCallUI/src/com/android/incallui/CallCommandClient.java index ae3be92ac..381d8d383 100644 --- a/InCallUI/src/com/android/incallui/CallCommandClient.java +++ b/InCallUI/src/com/android/incallui/CallCommandClient.java @@ -95,4 +95,23 @@ public class CallCommandClient { Logger.e(this, "Error setting speaker.", e); } } + + public void playDtmfTone(char digit, boolean timedShortTone) { + try { + Logger.v(this, "Sending dtmf tone " + digit); + mCommandService.playDtmfTone(digit, timedShortTone); + } catch (RemoteException e) { + Logger.e(this, "Error setting speaker.", e); + } + + } + + public void stopDtmfTone() { + try { + Logger.v(this, "Stop dtmf tone "); + mCommandService.stopDtmfTone(); + } catch (RemoteException e) { + Logger.e(this, "Error setting speaker.", e); + } + } } diff --git a/InCallUI/src/com/android/incallui/DialpadFragment.java b/InCallUI/src/com/android/incallui/DialpadFragment.java new file mode 100644 index 000000000..6be923cfb --- /dev/null +++ b/InCallUI/src/com/android/incallui/DialpadFragment.java @@ -0,0 +1,230 @@ +/* + * 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.content.Context; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.accessibility.AccessibilityManager; +import android.widget.EditText; + +import java.util.HashMap; + +/** + * Fragment for call control buttons + */ +public class DialpadFragment extends BaseFragment<DialpadPresenter> + implements DialpadPresenter.DialpadUi, View.OnTouchListener, View.OnKeyListener, + View.OnHoverListener, View.OnClickListener { + + private EditText mDtmfDialerField; + + /** Hash Map to map a view id to a character*/ + private static final HashMap<Integer, Character> mDisplayMap = + new HashMap<Integer, Character>(); + + /** Set up the static maps*/ + static { + // Map the buttons to the display characters + mDisplayMap.put(R.id.one, '1'); + mDisplayMap.put(R.id.two, '2'); + mDisplayMap.put(R.id.three, '3'); + mDisplayMap.put(R.id.four, '4'); + mDisplayMap.put(R.id.five, '5'); + mDisplayMap.put(R.id.six, '6'); + mDisplayMap.put(R.id.seven, '7'); + mDisplayMap.put(R.id.eight, '8'); + mDisplayMap.put(R.id.nine, '9'); + mDisplayMap.put(R.id.zero, '0'); + mDisplayMap.put(R.id.pound, '#'); + mDisplayMap.put(R.id.star, '*'); + } + + @Override + public void onClick(View v) { + Logger.d(this, "onClick"); + final AccessibilityManager accessibilityManager = (AccessibilityManager) + getActivity().getSystemService(Context.ACCESSIBILITY_SERVICE); + // When accessibility is on, simulate press and release to preserve the + // semantic meaning of performClick(). Required for Braille support. + if (accessibilityManager.isEnabled()) { + final int id = v.getId(); + // Checking the press state prevents double activation. + if (!v.isPressed() && mDisplayMap.containsKey(id)) { + getPresenter().processDtmf(mDisplayMap.get(id), true /* timedShortTone */); + } + } + } + + @Override + public boolean onHover(View v, MotionEvent event) { + // When touch exploration is turned on, lifting a finger while inside + // the button's hover target bounds should perform a click action. + final AccessibilityManager accessibilityManager = (AccessibilityManager) + getActivity().getSystemService(Context.ACCESSIBILITY_SERVICE); + + if (accessibilityManager.isEnabled() + && accessibilityManager.isTouchExplorationEnabled()) { + final int left = v.getPaddingLeft(); + final int right = (v.getWidth() - v.getPaddingRight()); + final int top = v.getPaddingTop(); + final int bottom = (v.getHeight() - v.getPaddingBottom()); + + switch (event.getActionMasked()) { + case MotionEvent.ACTION_HOVER_ENTER: + // Lift-to-type temporarily disables double-tap activation. + v.setClickable(false); + break; + case MotionEvent.ACTION_HOVER_EXIT: + final int x = (int) event.getX(); + final int y = (int) event.getY(); + if ((x > left) && (x < right) && (y > top) && (y < bottom)) { + v.performClick(); + } + v.setClickable(true); + break; + } + } + + return false; + } + + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + Logger.d(this, "onKey: keyCode " + keyCode + ", view " + v); + + if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { + int viewId = v.getId(); + if (mDisplayMap.containsKey(viewId)) { + switch (event.getAction()) { + case KeyEvent.ACTION_DOWN: + if (event.getRepeatCount() == 0) { + getPresenter().processDtmf(mDisplayMap.get(viewId)); + } + break; + case KeyEvent.ACTION_UP: + getPresenter().stopTone(); + break; + } + // do not return true [handled] here, since we want the + // press / click animation to be handled by the framework. + } + } + return false; + } + + @Override + public boolean onTouch(View v, MotionEvent event) { + Logger.d(this, "onTouch"); + int viewId = v.getId(); + + // if the button is recognized + if (mDisplayMap.containsKey(viewId)) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + // Append the character mapped to this button, to the display. + // start the tone + getPresenter().processDtmf(mDisplayMap.get(viewId)); + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + // stop the tone on ANY other event, except for MOVE. + getPresenter().stopTone(); + break; + } + // do not return true [handled] here, since we want the + // press / click animation to be handled by the framework. + } + return false; + } + + // TODO(klp) Adds hardware keyboard listener + + @Override + DialpadPresenter createPresenter() { + return new DialpadPresenter(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + final View parent = inflater.inflate( + com.android.incallui.R.layout.dtmf_twelve_key_dialer_view, container, false); + mDtmfDialerField = (EditText) parent.findViewById(R.id.dtmfDialerField); + if (mDtmfDialerField != null) { + // remove the long-press context menus that support + // the edit (copy / paste / select) functions. + mDtmfDialerField.setLongClickable(false); + + setupKeypad(parent); + } + getPresenter().onUiReady(this); + return parent; + } + + @Override + public void setVisible(boolean on) { + if (on) { + getView().setVisibility(View.VISIBLE); + } else { + getView().setVisibility(View.INVISIBLE); + } + } + + @Override + public void appendDigitsToField(char digit) { + if (mDtmfDialerField != null) { + // TODO: maybe *don't* manually append this digit if + // mDialpadDigits is focused and this key came from the HW + // keyboard, since in that case the EditText field will + // get the key event directly and automatically appends + // whetever the user types. + // (Or, a cleaner fix would be to just make mDialpadDigits + // *not* handle HW key presses. That seems to be more + // complicated than just setting focusable="false" on it, + // though.) + mDtmfDialerField.getText().append(digit); + } + } + + /** + * setup the keys on the dialer activity, using the keymaps. + */ + private void setupKeypad(View parent) { + // for each view id listed in the displaymap + View button; + for (int viewId : mDisplayMap.keySet()) { + // locate the view + button = parent.findViewById(viewId); + // Setup the listeners for the buttons + button.setOnTouchListener(this); + button.setClickable(true); + button.setOnKeyListener(this); + button.setOnHoverListener(this); + button.setOnClickListener(this); + } + } +} diff --git a/InCallUI/src/com/android/incallui/DialpadPresenter.java b/InCallUI/src/com/android/incallui/DialpadPresenter.java new file mode 100644 index 000000000..727c90dc8 --- /dev/null +++ b/InCallUI/src/com/android/incallui/DialpadPresenter.java @@ -0,0 +1,81 @@ +/* + * 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.telephony.PhoneNumberUtils; + +/** + * Logic for call buttons. + */ +public class DialpadPresenter extends Presenter<DialpadPresenter.DialpadUi> + implements InCallPresenter.InCallStateListener { + + @Override + public void onUiReady(DialpadUi ui) { + super.onUiReady(ui); + } + + @Override + public void onStateChange(InCallPresenter.InCallState state, CallList callList) { + + } + + /** + * Processes the specified digit as a DTMF key, by playing the + * appropriate DTMF tone, and appending the digit to the EditText + * field that displays the DTMF digits sent so far. + * + * @see #processDtmf(char, boolean) + */ + public final void processDtmf(char c) { + processDtmf(c, false); + } + + /** + * Processes the specified digit as a DTMF key, by playing the appropriate + * DTMF tone (or short tone if requested), and appending the digit to the + * EditText field that displays the DTMF digits sent so far. + */ + // TODO(klp) Add timedShortTone==true handling for accessibility cases. + public final void processDtmf(char c, boolean timedShortTone) { + Logger.d(this, "Processing dtmf key " + c); + // if it is a valid key, then update the display and send the dtmf tone. + if (PhoneNumberUtils.is12Key(c)) { + Logger.d(this, "updating display and sending dtmf tone for '" + c + "'"); + + // Append this key to the "digits" widget. + getUi().appendDigitsToField(c); + // Plays the tone through CallCommandService + CallCommandClient.getInstance().playDtmfTone(c, timedShortTone); + } else { + Logger.d(this, "ignoring dtmf request for '" + c + "'"); + } + } + + /** + * Stops the local tone based on the phone type. + */ + public void stopTone() { + Logger.d(this, "stopping remote tone"); + CallCommandClient.getInstance().stopDtmfTone(); + } + + public interface DialpadUi extends Ui { + void setVisible(boolean on); + void appendDigitsToField(char digit); + } +} diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java index 9eb54ee5e..28e02b3b3 100644 --- a/InCallUI/src/com/android/incallui/InCallActivity.java +++ b/InCallUI/src/com/android/incallui/InCallActivity.java @@ -33,6 +33,7 @@ public class InCallActivity extends Activity { private CallButtonFragment mCallButtonFragment; private CallCardFragment mCallCardFragment; private AnswerFragment mAnswerFragment; + private DialpadFragment mDialpadFragment; @Override protected void onCreate(Bundle icicle) { @@ -133,7 +134,16 @@ public class InCallActivity extends Activity { @Override public void onBackPressed() { - // TODO(klp): implement + // TODO(klp): implement fully + Logger.d(this, "onBackPressed()..."); + + // BACK is also used to exit out of any "special modes" of the + // in-call UI: + + if (mDialpadFragment.isVisible()) { + mCallButtonFragment.displayDialpad(false); // do the "closing" animation + return; + } // Nothing special to do. Fall back to the default behavior. super.onBackPressed(); @@ -185,8 +195,7 @@ public class InCallActivity extends Activity { break; } - // TODO(klp): handle dialer key down - + // TODO(klp) Adds hardware keyboard support return super.onKeyDown(keyCode, event); } @@ -208,6 +217,12 @@ public class InCallActivity extends Activity { .findFragmentById(R.id.answerFragment); } + if (mDialpadFragment == null) { + mDialpadFragment = (DialpadFragment) getFragmentManager() + .findFragmentById(R.id.dialpadFragment); + mDialpadFragment.getView().setVisibility(View.INVISIBLE); + } + setUpPresenters(); } @@ -235,4 +250,14 @@ public class InCallActivity extends Activity { toast.show(); } + + public void displayDialpad(boolean showDialpad) { + if (showDialpad) { + mDialpadFragment.setVisible(true); + mCallCardFragment.setVisible(false); + } else { + mDialpadFragment.setVisible(false); + mCallCardFragment.setVisible(true); + } + } } |