summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVinit Deshpande <vinitd@google.com>2015-04-15 00:29:47 -0700
committerVinit Deshpande <vinitd@google.com>2015-04-15 00:29:47 -0700
commit01ad85125dd7cbe1107c679dcc362b9487700b9a (patch)
treef7b9a01c7e24f699fbc6fb806607478a207b563f
parent7fd5e5b73e2279d07eed498c46565e7bb170a3b0 (diff)
parent9e0d3a386a48d5f32dacb45bab96f0ea5752be36 (diff)
am b04d61a..697f674 from mirror-m-wireless-internal-release
697f674 Fix orientation of preview surface when device rotated. 17de502 Merge "Always allow landscape mode if video call is the primary call" into m-wireless-dev 3692e77 Always allow landscape mode if video call is the primary call a77ad8d Video calling landscape changes to match specs cb74fc0 Merge "Simplify and rewire in-call buttons" into m-wireless-dev ed0775d Simplify and rewire in-call buttons 80a1aad Hide incoming video until call is connected. 4f2a70b Merge "Cleanup AnswerFragment glowpad UI" into m-wireless-dev 6591f05 Merge "Initial refactoring for call buttons" into m-wireless-dev c70a63c Initial refactoring for call buttons 4a63afd Hide end call button when video upgrade glowpad is showing 7ba13e9 Cleanup AnswerFragment glowpad UI 6b2b8df Show progress spinner when upgrading to video c02794b Merge "Cleanup of Video Call pause functionality." into m-wireless-dev bec5807 Standardize fragment layout names bc65cbc Adding video call icon in secondary call info.
-rw-r--r--InCallUI/res/drawable-land/rounded_call_card_background.xml (renamed from InCallUI/res/drawable/ic_lockscreen_answer_rx_video_activated_layer.xml)21
-rw-r--r--InCallUI/res/drawable/ic_lockscreen_answer_rx_video.xml30
-rw-r--r--InCallUI/res/drawable/ic_lockscreen_answer_rx_video_normal_layer.xml36
-rw-r--r--InCallUI/res/drawable/ic_lockscreen_answer_tx_video.xml30
-rw-r--r--InCallUI/res/drawable/ic_lockscreen_answer_tx_video_normal_layer.xml36
-rw-r--r--InCallUI/res/layout-land/call_card_fragment.xml36
-rw-r--r--InCallUI/res/layout/call_button_fragment.xml12
-rw-r--r--InCallUI/res/layout/call_card_fragment.xml7
-rw-r--r--InCallUI/res/layout/secondary_call_info.xml7
-rw-r--r--InCallUI/res/menu/incall_overflow_menu.xml36
-rw-r--r--InCallUI/res/values-land/colors.xml (renamed from InCallUI/res/drawable/ic_lockscreen_answer_tx_video_activated_layer.xml)19
-rw-r--r--InCallUI/res/values-land/dimens.xml5
-rw-r--r--InCallUI/res/values/array.xml21
-rw-r--r--InCallUI/res/values/colors.xml2
-rw-r--r--InCallUI/res/values/dimens.xml5
-rw-r--r--InCallUI/res/values/strings.xml25
-rw-r--r--InCallUI/src/com/android/incallui/CallButtonFragment.java283
-rw-r--r--InCallUI/src/com/android/incallui/CallButtonPresenter.java200
-rw-r--r--InCallUI/src/com/android/incallui/CallCardFragment.java37
-rw-r--r--InCallUI/src/com/android/incallui/CallCardPresenter.java43
-rw-r--r--InCallUI/src/com/android/incallui/DialpadFragment.java2
-rw-r--r--InCallUI/src/com/android/incallui/GlowPadWrapper.java8
-rw-r--r--InCallUI/src/com/android/incallui/InCallActivity.java15
-rw-r--r--InCallUI/src/com/android/incallui/InCallPresenter.java11
-rw-r--r--InCallUI/src/com/android/incallui/InCallVideoCallListener.java4
-rw-r--r--InCallUI/src/com/android/incallui/VideoCallFragment.java89
-rw-r--r--InCallUI/src/com/android/incallui/VideoCallPresenter.java95
-rw-r--r--InCallUI/src/com/android/incallui/VideoPauseController.java239
28 files changed, 607 insertions, 747 deletions
diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_rx_video_activated_layer.xml b/InCallUI/res/drawable-land/rounded_call_card_background.xml
index 750ef5e26..f41ecda79 100644
--- a/InCallUI/res/drawable/ic_lockscreen_answer_rx_video_activated_layer.xml
+++ b/InCallUI/res/drawable-land/rounded_call_card_background.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
+
<!--
- ~ Copyright (c) 2014, The Linux Foundation. All rights reserved.
- ~ Not a Contribution.
- ~ Copyright (C) 2014 The Android Open Source Project
+ ~ Copyright (C) 2015 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -16,13 +15,9 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/fab_red" />
- <item>
- <bitmap
- android:gravity="center"
- android:src="@drawable/ic_rx_videocam"
- android:tint="@color/glowpad_widget_active_color"
- android:autoMirrored="true" />
- </item>
-</layer-list>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="@color/incall_call_banner_background_color" />
+ <corners
+ android:radius="4dp" />
+</shape> \ No newline at end of file
diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_rx_video.xml b/InCallUI/res/drawable/ic_lockscreen_answer_rx_video.xml
deleted file mode 100644
index c5a41d814..000000000
--- a/InCallUI/res/drawable/ic_lockscreen_answer_rx_video.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (c) 2014, The Linux Foundation. All rights reserved.
- ~ Not a Contribution.
- ~ Copyright (C) 2014 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
- -->
-<!-- Used with incoming call wigdet. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:state_enabled="true" android:state_active="false" android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_answer_rx_video_normal_layer"/>
- <item
- android:state_enabled="true" android:state_active="true" android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_answer_rx_video_activated_layer" />
- <item
- android:state_enabled="true" android:state_active="false" android:state_focused="true"
- android:drawable="@drawable/ic_lockscreen_answer_rx_video_activated_layer" />
-</selector>
diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_rx_video_normal_layer.xml b/InCallUI/res/drawable/ic_lockscreen_answer_rx_video_normal_layer.xml
deleted file mode 100644
index 5efd3d142..000000000
--- a/InCallUI/res/drawable/ic_lockscreen_answer_rx_video_normal_layer.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (c) 2014, The Linux Foundation. All rights reserved.
- ~ Not a Contribution.
- ~ Copyright (C) 2014 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
- -->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- A fake circle to fix the size of this layer asset. -->
- <item>
- <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
- <solid android:color="#00000000"/>
- <size
- android:width="@dimen/incoming_call_widget_circle_size"
- android:height="@dimen/incoming_call_widget_circle_size" />
- </shape>
- </item>
- <item>
- <bitmap
- android:gravity="center"
- android:src="@drawable/ic_rx_videocam"
- android:tint="@color/glowpad_call_widget_normal_tint"
- android:autoMirrored="true" />
- </item>
-</layer-list>
diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_tx_video.xml b/InCallUI/res/drawable/ic_lockscreen_answer_tx_video.xml
deleted file mode 100644
index 15d11978e..000000000
--- a/InCallUI/res/drawable/ic_lockscreen_answer_tx_video.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (c) 2014, The Linux Foundation. All rights reserved.
- ~ Not a Contribution.
- ~ Copyright (C) 2014 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
- -->
-<!-- Used with incoming call wigdet. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:state_enabled="true" android:state_active="false" android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_answer_tx_video_normal_layer"/>
- <item
- android:state_enabled="true" android:state_active="true" android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_answer_tx_video_activated_layer" />
- <item
- android:state_enabled="true" android:state_active="false" android:state_focused="true"
- android:drawable="@drawable/ic_lockscreen_answer_tx_video_activated_layer" />
-</selector>
diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_tx_video_normal_layer.xml b/InCallUI/res/drawable/ic_lockscreen_answer_tx_video_normal_layer.xml
deleted file mode 100644
index b0ad943dc..000000000
--- a/InCallUI/res/drawable/ic_lockscreen_answer_tx_video_normal_layer.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (c) 2014, The Linux Foundation. All rights reserved.
- ~ Not a Contribution.
- ~ Copyright (C) 2014 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
- -->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- A fake circle to fix the size of this layer asset. -->
- <item>
- <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
- <solid android:color="#00000000"/>
- <size
- android:width="@dimen/incoming_call_widget_circle_size"
- android:height="@dimen/incoming_call_widget_circle_size" />
- </shape>
- </item>
- <item>
- <bitmap
- android:gravity="center"
- android:src="@drawable/ic_tx_videocam"
- android:tint="@color/glowpad_call_widget_normal_tint"
- android:autoMirrored="true" />
- </item>
-</layer-list>
diff --git a/InCallUI/res/layout-land/call_card_fragment.xml b/InCallUI/res/layout-land/call_card_fragment.xml
index cdee27970..89466152a 100644
--- a/InCallUI/res/layout-land/call_card_fragment.xml
+++ b/InCallUI/res/layout-land/call_card_fragment.xml
@@ -30,22 +30,25 @@
android:layout_height="match_parent"
android:orientation="vertical"
android:elevation="@dimen/primary_call_elevation"
- android:background="@color/incall_call_banner_background_color"
+ android:background="@drawable/rounded_call_card_background"
android:paddingTop="@dimen/call_banner_primary_call_container_top_padding"
android:clipChildren="false"
- android:clipToPadding="false" >
+ android:clipToPadding="false"
+ android:alpha="0.9"
+ android:layout_margin="10dp">
<include layout="@layout/primary_call_info" />
- <fragment android:name="com.android.incallui.CallButtonFragment"
- android:id="@+id/callButtonFragment"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
<FrameLayout
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="match_parent" >
+ <fragment android:name="com.android.incallui.CallButtonFragment"
+ android:id="@+id/callButtonFragment"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:layout_marginBottom="@dimen/call_buttons_bottom_margin" />
<!-- Secondary "Call info" block, for the background ("on hold") call. -->
<include layout="@layout/secondary_call_info"
android:layout_width="match_parent"
@@ -73,14 +76,6 @@
android:layout_height="wrap_content"
android:layout_alignTop="@id/photo" />
- <fragment android:name="com.android.incallui.VideoCallFragment"
- android:layout_alignParentStart="true"
- android:layout_gravity="start|center_vertical"
- android:id="@+id/videoCallFragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone" />
-
<!-- Progress spinner, useful for indicating pending operations such as upgrade to video. -->
<FrameLayout
android:id="@+id/progressSpinner"
@@ -102,7 +97,14 @@
</FrameLayout>
- <!-- Placeholder for various fragments that are added dynamically underneath the caller info. -->
+ <fragment android:name="com.android.incallui.VideoCallFragment"
+ android:layout_alignParentStart="true"
+ android:layout_gravity="start|center_vertical"
+ android:id="@+id/videoCallFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <!-- Placeholder for the dialpad which is replaced with the dialpad fragment when shown. -->
<FrameLayout
android:id="@+id/answer_and_dialpad_container"
android:layout_toEndOf="@id/primary_call_info_container"
diff --git a/InCallUI/res/layout/call_button_fragment.xml b/InCallUI/res/layout/call_button_fragment.xml
index 604d79e60..3629b8a3b 100644
--- a/InCallUI/res/layout/call_button_fragment.xml
+++ b/InCallUI/res/layout/call_button_fragment.xml
@@ -67,7 +67,8 @@
<ToggleButton android:id="@+id/audioButton"
style="@style/InCallCompoundButton"
android:background="@drawable/btn_compound_audio"
- android:contentDescription="@string/audio_mode_speaker" />
+ android:contentDescription="@string/audio_mode_speaker"
+ android:visibility="gone" />
<!-- "Change to audio call" for video calls. -->
<ImageButton android:id="@+id/changeToVoiceButton"
@@ -82,7 +83,8 @@
<ToggleButton android:id="@+id/muteButton"
style="@style/InCallCompoundButton"
android:background="@drawable/btn_compound_mute"
- android:contentDescription="@string/onscreenMuteText" />
+ android:contentDescription="@string/onscreenMuteText"
+ android:visibility="gone" />
<!-- CENTER SLOT ======================================================================= -->
@@ -90,7 +92,8 @@
<ToggleButton android:id="@+id/dialpadButton"
style="@style/InCallCompoundButton"
android:background="@drawable/btn_compound_dialpad"
- android:contentDescription="@string/onscreenShowDialpadText" />
+ android:contentDescription="@string/onscreenShowDialpadText"
+ android:visibility="gone" />
<!-- MIDDLE RIGHT SLOT ================================================================= -->
@@ -101,7 +104,8 @@
<ToggleButton android:id="@+id/holdButton"
style="@style/InCallCompoundButton"
android:background="@drawable/btn_compound_hold"
- android:contentDescription="@string/onscreenHoldText" />
+ android:contentDescription="@string/onscreenHoldText_unselected"
+ android:visibility="gone" />
<!-- "Swap" (or "Manage calls" in some CDMA states) -->
<ImageButton android:id="@+id/swapButton"
diff --git a/InCallUI/res/layout/call_card_fragment.xml b/InCallUI/res/layout/call_card_fragment.xml
index 615744c79..d28ffe018 100644
--- a/InCallUI/res/layout/call_card_fragment.xml
+++ b/InCallUI/res/layout/call_card_fragment.xml
@@ -93,6 +93,13 @@
</FrameLayout>
+ <fragment android:name="com.android.incallui.VideoCallFragment"
+ android:id="@+id/videoCallFragment"
+ android:layout_alignParentTop="true"
+ android:layout_gravity="top|center_horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
<!-- Secondary "Call info" block, for the background ("on hold") call. -->
<include layout="@layout/secondary_call_info" />
diff --git a/InCallUI/res/layout/secondary_call_info.xml b/InCallUI/res/layout/secondary_call_info.xml
index 85eef0ee1..e866795a6 100644
--- a/InCallUI/res/layout/secondary_call_info.xml
+++ b/InCallUI/res/layout/secondary_call_info.xml
@@ -40,6 +40,13 @@
android:paddingBottom="@dimen/secondary_call_info_vertical_padding"
android:background="?android:attr/selectableItemBackground">
+ <ImageView android:id="@+id/secondaryCallVideoCallIcon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_toolbar_video"
+ android:tint="@color/incall_banner_secondary_text_color"
+ android:paddingEnd="16dp"/>
+
<ImageView android:id="@+id/secondaryCallConferenceCallIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/InCallUI/res/menu/incall_overflow_menu.xml b/InCallUI/res/menu/incall_overflow_menu.xml
deleted file mode 100644
index 2de858711..000000000
--- a/InCallUI/res/menu/incall_overflow_menu.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2014 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
- -->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:id="@+id/overflow_merge_menu_item"
- android:title="@string/overflowMergeMenuItemText" />
-
- <item android:id="@+id/overflow_add_menu_item"
- android:title="@string/overflowAddMenuItemText" />
-
- <item android:id="@+id/overflow_hold_menu_item"
- android:title="@string/overflowHoldMenuItemText" />
-
- <item android:id="@+id/overflow_resume_menu_item"
- android:title="@string/overflowResumeMenuItemText" />
-
- <item android:id="@+id/overflow_swap_menu_item"
- android:title="@string/overflowSwapMenuItemText" />
-
- <item android:id="@+id/overflow_manage_conference_menu_item"
- android:title="@string/overflowManageConferenceMenuItemText" />
-</menu>
diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_tx_video_activated_layer.xml b/InCallUI/res/values-land/colors.xml
index c1dca4d06..77eea2e68 100644
--- a/InCallUI/res/drawable/ic_lockscreen_answer_tx_video_activated_layer.xml
+++ b/InCallUI/res/values-land/colors.xml
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (c) 2014, The Linux Foundation. All rights reserved.
- ~ Not a Contribution.
- ~ Copyright (C) 2014 The Android Open Source Project
+ ~ Copyright (C) 2015 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -16,13 +14,8 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/fab_green" />
- <item>
- <bitmap
- android:gravity="center"
- android:src="@drawable/ic_tx_videocam"
- android:tint="@color/glowpad_widget_active_color"
- android:autoMirrored="true" />
- </item>
-</layer-list>
+
+<resources>
+ <!-- Background color for status bar. For portrait this will be ignored. -->
+ <color name="statusbar_background_color">#000000</color>
+</resources>
diff --git a/InCallUI/res/values-land/dimens.xml b/InCallUI/res/values-land/dimens.xml
index d992ccdea..59a5a9a87 100644
--- a/InCallUI/res/values-land/dimens.xml
+++ b/InCallUI/res/values-land/dimens.xml
@@ -16,6 +16,11 @@
-->
<resources>
+ <!-- Whether or not the landscape mode layout is currently being used -->
+ <bool name="is_layout_landscape">true</bool>
<!-- Height and width of the in-call buttons. -->
<dimen name="in_call_button_dimension">40dp</dimen>
+ <!-- Margin underneath the call buttons. This is used only in landscape mode and is sized
+ so that the call buttons are center aligned with the end call button. -->
+ <dimen name="call_buttons_bottom_margin">30dp</dimen>
</resources>
diff --git a/InCallUI/res/values/array.xml b/InCallUI/res/values/array.xml
index 46592e126..2e38c2c46 100644
--- a/InCallUI/res/values/array.xml
+++ b/InCallUI/res/values/array.xml
@@ -74,8 +74,6 @@
<item>@null</item>
<item>@drawable/ic_lockscreen_decline</item>
<item>@drawable/ic_lockscreen_answer_video</item>
- <item>@drawable/ic_lockscreen_answer_tx_video</item>
- <item>@drawable/ic_lockscreen_answer_rx_video</item>
</array>
<array name="incoming_call_widget_video_without_sms_target_descriptions">
<item>@string/description_target_answer_video_call</item>
@@ -100,8 +98,6 @@
<item>@drawable/ic_lockscreen_text</item>
<item>@drawable/ic_lockscreen_decline</item>
<item>@drawable/ic_lockscreen_answer</item>
- <item>@drawable/ic_lockscreen_answer_tx_video</item>
- <item>@drawable/ic_lockscreen_answer_rx_video</item>
</array>
<array name="incoming_call_widget_video_with_sms_target_descriptions">
<item>@string/description_target_answer_video_call</item>
@@ -126,8 +122,6 @@
<item>@null</item>
<item>@drawable/ic_lockscreen_decline</item>
<item>@drawable/ic_lockscreen_answer</item>
- <item>@drawable/ic_lockscreen_answer_tx_video</item>
- <item>@drawable/ic_lockscreen_answer_rx_video</item>
</array>
<array name="incoming_call_widget_video_upgrade_request_target_descriptions">
<item>@string/description_target_accept_upgrade_to_video_request</item>
@@ -152,26 +146,27 @@
<!-- For accept/reject upgrade to video transmit in active video call
- Accept upgrade to video request (drag right)
- - Decline upgrade to video request (drag left)-->
+ - Decline upgrade to video request (drag left)
+ TODO: This should be automatically rejected in the lower layers -->
<array name="incoming_call_widget_video_transmit_accept_reject_request_targets">
- <item>@drawable/ic_lockscreen_answer_tx_video</item>
+ <item>@drawable/ic_lockscreen_answer_video</item>
<item>@drawable/ic_lockscreen_decline</item>
</array>
<array name="incoming_call_widget_video_transmit_request_target_descriptions">
- <item>@string/description_target_accept_upgrade_to_video_transmit_request</item>
- <item>@string/description_target_decline_upgrade_to_video_transmit_request</item>
+ <item>@string/description_target_accept_upgrade_to_video_request</item>
+ <item>@string/description_target_decline_upgrade_to_video_request</item>
</array>
<!-- For accept/reject upgrade to video receive in active video call
- Accept upgrade to video request (drag right)
- Decline upgrade to video request (drag left)-->
<array name="incoming_call_widget_video_receive_accept_reject_request_targets">
- <item>@drawable/ic_lockscreen_answer_rx_video</item>
+ <item>@drawable/ic_lockscreen_answer_video</item>
<item>@drawable/ic_lockscreen_decline</item>
</array>
<array name="incoming_call_widget_video_receive_request_target_descriptions">
- <item>@string/description_target_accept_upgrade_to_video_receive_request</item>
- <item>@string/description_target_decline_upgrade_to_video_receive_request</item>
+ <item>@string/description_target_accept_upgrade_to_video_request</item>
+ <item>@string/description_target_decline_upgrade_to_video_request</item>
</array>
</resources>
diff --git a/InCallUI/res/values/colors.xml b/InCallUI/res/values/colors.xml
index afc557bc1..cac382deb 100644
--- a/InCallUI/res/values/colors.xml
+++ b/InCallUI/res/values/colors.xml
@@ -59,6 +59,8 @@
<!-- Background color of action bars -->
<color name="actionbar_background_color">@color/dialer_theme_color</color>
+ <!-- Background color for status bar. For portrait this will be ignored. -->
+ <color name="statusbar_background_color">@color/dialer_theme_color</color>
<color name="translucent_shadow">#33999999</color>
diff --git a/InCallUI/res/values/dimens.xml b/InCallUI/res/values/dimens.xml
index 43307e8db..0739234f2 100644
--- a/InCallUI/res/values/dimens.xml
+++ b/InCallUI/res/values/dimens.xml
@@ -16,6 +16,9 @@
-->
<resources>
+ <!-- Whether or not the landscape mode layout is currently being used -->
+ <bool name="is_layout_landscape">false</bool>
+
<!-- Dimensions for CallCard elements (the normal in-call UI) -->
<!-- Height of the "call banner" overlay on top of the upper part of the call info area.
@@ -67,7 +70,7 @@
<dimen name="dialpad_digits_adjustable_height">50dp</dimen>
<dimen name="dialpad_key_numbers_size">36dp</dimen>
- <dimen name="floating_action_bar_vertical_offset">-24dp</dimen>
+ <dimen name="floating_action_button_vertical_offset">-24dp</dimen>
<dimen name="call_button_margin_vertical">8dp</dimen>
<dimen name="call_button_margin_horizontal">6dp</dimen>
diff --git a/InCallUI/res/values/strings.xml b/InCallUI/res/values/strings.xml
index 99b8111bb..cfe3d41ab 100644
--- a/InCallUI/res/values/strings.xml
+++ b/InCallUI/res/values/strings.xml
@@ -255,23 +255,14 @@
to dial using the physical keyboard -->
<string name="dialerKeyboardHintText">Use keyboard to dial</string>
- <!-- Text for the overflow "Hold call" menu item. -->
- <string name="overflowHoldMenuItemText">Hold call</string>
- <!-- Text for the overflow "Resume call" menu item. -->
- <string name="overflowResumeMenuItemText">Resume call</string>
- <!-- Text for the overflow "Add call" menu item. -->
- <string name="overflowAddMenuItemText">Add call</string>
- <!-- Text for the onscreen "Merge calls" menu item. -->
- <string name="overflowMergeMenuItemText">Merge calls</string>
- <!-- Text for the onscreen "Swap calls" menu item. -->
- <string name="overflowSwapMenuItemText">Swap calls</string>
- <!-- Text for the overflow "Manage Conference Video Call" menu item. -->
- <string name="overflowManageConferenceMenuItemText">Manage Conference</string>
-
- <!-- Text for the onscreen "Hold" button -->
- <string name="onscreenHoldText">Hold</string>
+ <!-- Text for the onscreen "Hold" button when it is not selected. Pressing it will put
+ the call on hold. -->
+ <string name="onscreenHoldText_unselected">Hold Call</string>
+ <!-- Text for the onscreen "Hold" button when it is selected. Pressing it will resume
+ the call from a previously held state. -->
+ <string name="onscreenHoldText_selected">Resume Call</string>
<!-- Text for the onscreen "End call" button -->
- <string name="onscreenEndCallText">End</string>
+ <string name="onscreenEndCallText">End Call</string>
<!-- Text for the onscreen "Show Dialpad" button -->
<string name="onscreenShowDialpadText">Dialpad</string>
<!-- Text for the onscreen "Mute" button -->
@@ -456,7 +447,7 @@
<!-- This can be used in any application wanting to disable the text "Emergency number" -->
<string name="emergency_call_dialog_number_for_display">Emergency number</string>
- <!-- STOPSHIP These strings are for debugging only -->
+ <!-- STOPSHIP These strings are for debugging only -->
<!-- Call substate label -->
<string name="call_substate_label" translatable="false">Call substate - \u000a</string>
<!-- Call substate label for call resumed -->
diff --git a/InCallUI/src/com/android/incallui/CallButtonFragment.java b/InCallUI/src/com/android/incallui/CallButtonFragment.java
index a9fafae18..b2c812b7b 100644
--- a/InCallUI/src/com/android/incallui/CallButtonFragment.java
+++ b/InCallUI/src/com/android/incallui/CallButtonFragment.java
@@ -16,6 +16,8 @@
package com.android.incallui;
+import static com.android.incallui.CallButtonFragment.Buttons.*;
+
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
@@ -30,6 +32,7 @@ import android.os.Bundle;
import android.telecom.AudioState;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
+import android.util.SparseIntArray;
import android.view.ContextThemeWrapper;
import android.view.HapticFeedbackConstants;
import android.view.LayoutInflater;
@@ -44,7 +47,6 @@ import android.widget.Toast;
import android.widget.PopupMenu.OnDismissListener;
import android.widget.PopupMenu.OnMenuItemClickListener;
-import com.android.contacts.common.util.MaterialColorMapUtils;
import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
import java.util.ArrayList;
@@ -55,8 +57,34 @@ public class CallButtonFragment
extends BaseFragment<CallButtonPresenter, CallButtonPresenter.CallButtonUi>
implements CallButtonPresenter.CallButtonUi, OnMenuItemClickListener, OnDismissListener,
View.OnClickListener {
- private CompoundButton mAudioButton;
private static final int INVALID_INDEX = -1;
+ private static final int BUTTON_MAX_VISIBLE = 5;
+ // The button is currently visible in the UI
+ private static final int BUTTON_VISIBLE = 1;
+ // The button is hidden in the UI
+ private static final int BUTTON_HIDDEN = 2;
+ // The button has been collapsed into the overflow menu
+ private static final int BUTTON_MENU = 3;
+
+ public interface Buttons {
+ public static final int BUTTON_AUDIO = 0;
+ public static final int BUTTON_DOWNGRADE_TO_VOICE = 1;
+ public static final int BUTTON_MUTE = 2;
+ public static final int BUTTON_DIALPAD = 3;
+ public static final int BUTTON_HOLD = 4;
+ public static final int BUTTON_SWAP = 5;
+ public static final int BUTTON_UPGRADE_TO_VIDEO = 6;
+ public static final int BUTTON_SWITCH_CAMERA = 7;
+ public static final int BUTTON_ADD_CALL = 8;
+ public static final int BUTTON_MERGE = 9;
+ public static final int BUTTON_PAUSE_VIDEO = 10;
+ public static final int BUTTON_MANAGE_VIDEO_CONFERENCE = 11;
+ public static final int BUTTON_COUNT = 12;
+ }
+
+ private SparseIntArray mButtonVisibilityMap = new SparseIntArray(BUTTON_COUNT);
+
+ private CompoundButton mAudioButton;
private ImageButton mChangeToVoiceButton;
private CompoundButton mMuteButton;
private CompoundButton mShowDialpadButton;
@@ -97,6 +125,10 @@ public class CallButtonFragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
+ for (int i = 0; i < BUTTON_COUNT; i++) {
+ mButtonVisibilityMap.put(i, BUTTON_HIDDEN);
+ }
}
@Override
@@ -157,7 +189,6 @@ public class CallButtonFragment
int id = view.getId();
Log.d(this, "onClick(View " + view + ", id " + id + ")...");
- boolean isClickHandled = true;
switch(id) {
case R.id.audioButton:
onAudioButtonClicked();
@@ -200,22 +231,21 @@ public class CallButtonFragment
!mPauseVideoButton.isSelected() /* pause */);
break;
case R.id.overflowButton:
- mOverflowPopup.show();
+ if (mOverflowPopup != null) {
+ mOverflowPopup.show();
+ }
break;
case R.id.manageVideoCallConferenceButton:
onManageVideoCallConferenceClicked();
break;
default:
- isClickHandled = false;
Log.wtf(this, "onClick: unexpected");
- break;
+ return;
}
- if (isClickHandled) {
- view.performHapticFeedback(
- HapticFeedbackConstants.VIRTUAL_KEY,
- HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
- }
+ view.performHapticFeedback(
+ HapticFeedbackConstants.VIRTUAL_KEY,
+ HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
}
public void updateColors() {
@@ -225,7 +255,6 @@ public class CallButtonFragment
return;
}
- Resources res = getActivity().getResources();
View[] compoundButtons = {
mAudioButton,
mMuteButton,
@@ -344,112 +373,81 @@ public class CallButtonFragment
}
@Override
- public void setMute(boolean value) {
- if (mMuteButton.isSelected() != value) {
- mMuteButton.setSelected(value);
- }
- }
-
- @Override
- public void showAudioButton(boolean show) {
- mAudioButton.setVisibility(show ? View.VISIBLE : View.GONE);
- }
-
- @Override
- public void showChangeToVoiceButton(boolean show) {
- mChangeToVoiceButton.setVisibility(show ? View.VISIBLE : View.GONE);
+ public void showButton(int buttonId, boolean show) {
+ mButtonVisibilityMap.put(buttonId, show ? BUTTON_VISIBLE : BUTTON_HIDDEN);
}
@Override
- public void enableMute(boolean enabled) {
- mMuteButton.setEnabled(enabled);
+ public void enableButton(int buttonId, boolean enable) {
+ final View button = getButtonById(buttonId);
+ if (button != null) {
+ button.setEnabled(enable);
+ }
}
- @Override
- public void showDialpadButton(boolean show) {
- mShowDialpadButton.setVisibility(show ? View.VISIBLE : View.GONE);
+ private View getButtonById(int id) {
+ switch (id) {
+ case BUTTON_AUDIO:
+ return mAudioButton;
+ case BUTTON_DOWNGRADE_TO_VOICE:
+ return mChangeToVoiceButton;
+ case BUTTON_MUTE:
+ return mMuteButton;
+ case BUTTON_DIALPAD:
+ return mShowDialpadButton;
+ case BUTTON_HOLD:
+ return mHoldButton;
+ case BUTTON_SWAP:
+ return mSwapButton;
+ case BUTTON_UPGRADE_TO_VIDEO:
+ return mChangeToVideoButton;
+ case BUTTON_SWITCH_CAMERA:
+ return mSwitchCameraButton;
+ case BUTTON_ADD_CALL:
+ return mAddCallButton;
+ case BUTTON_MERGE:
+ return mMergeButton;
+ case BUTTON_PAUSE_VIDEO:
+ return mPauseVideoButton;
+ case BUTTON_MANAGE_VIDEO_CONFERENCE:
+ return mManageVideoCallConferenceButton;
+ default:
+ Log.w(this, "Invalid button id");
+ return null;
+ }
}
@Override
public void setHold(boolean value) {
if (mHoldButton.isSelected() != value) {
mHoldButton.setSelected(value);
+ mHoldButton.setContentDescription(getContext().getString(
+ value ? R.string.onscreenHoldText_selected
+ : R.string.onscreenHoldText_unselected));
}
}
@Override
- public void showHoldButton(boolean show) {
- mHoldButton.setVisibility(show ? View.VISIBLE : View.GONE);
- }
-
- @Override
- public void enableHold(boolean enabled) {
- mHoldButton.setEnabled(enabled);
- }
-
- @Override
- public void showSwapButton(boolean show) {
- mSwapButton.setVisibility(show ? View.VISIBLE : View.GONE);
- }
-
- @Override
- public void showChangeToVideoButton(boolean show) {
- mChangeToVideoButton.setVisibility(show ? View.VISIBLE : View.GONE);
- }
-
- @Override
- public void enableChangeToVideoButton(boolean enable) {
- mChangeToVideoButton.setEnabled(enable);
- }
-
- @Override
- public void showSwitchCameraButton(boolean show) {
- mSwitchCameraButton.setVisibility(show ? View.VISIBLE : View.GONE);
- }
-
- @Override
- public void setSwitchCameraButton(boolean isBackFacingCamera) {
+ public void setCameraSwitched(boolean isBackFacingCamera) {
mSwitchCameraButton.setSelected(isBackFacingCamera);
}
@Override
- public void showAddCallButton(boolean show) {
- Log.d(this, "show Add call button: " + show);
- mAddCallButton.setVisibility(show ? View.VISIBLE : View.GONE);
- }
-
- public void showManageConferenceVideoCallButton(boolean show) {
- mManageVideoCallConferenceButton.setVisibility(show ? View.VISIBLE : View.GONE);
- }
-
- @Override
- public void showMergeButton(boolean show) {
- mMergeButton.setVisibility(show ? View.VISIBLE : View.GONE);
-
- // If the merge button was disabled, re-enable it when hiding it.
- if (!show) {
- mMergeButton.setEnabled(true);
- }
- }
-
- @Override
- public void showPauseVideoButton(boolean show) {
- mPauseVideoButton.setVisibility(show ? View.VISIBLE : View.GONE);
- }
-
- @Override
- public void setPauseVideoButton(boolean isPaused) {
+ public void setVideoPaused(boolean isPaused) {
mPauseVideoButton.setSelected(isPaused);
}
@Override
- public void showOverflowButton(boolean show) {
- mOverflowButton.setVisibility(show ? View.VISIBLE : View.GONE);
+ public void setMute(boolean value) {
+ if (mMuteButton.isSelected() != value) {
+ mMuteButton.setSelected(value);
+ }
}
/**The function is called when Modify Call button gets pressed. The function creates and
* displays modify call options.
*/
+ @Override
public void displayModifyCallOptions() {
CallButtonPresenter.CallButtonUi ui = getUi();
if (ui == null) {
@@ -520,65 +518,68 @@ public class CallButtonFragment
return "";
}
+ private void addToOverflowMenu(int id, View button, PopupMenu menu) {
+ button.setVisibility(View.GONE);
+ menu.getMenu().add(Menu.NONE, id, Menu.NONE, button.getContentDescription());
+ mButtonVisibilityMap.put(id, BUTTON_MENU);
+ }
+
+ private PopupMenu getPopupMenu() {
+ return new PopupMenu(new ContextThemeWrapper(getActivity(), R.style.InCallPopupMenuStyle),
+ mOverflowButton);
+ }
+
+ /**
+ * Iterates through the list of buttons and toggles their visibility depending on the
+ * setting configured by the CallButtonPresenter. If there are more visible buttons than
+ * the allowed maximum, the excess buttons are collapsed into a single overflow menu.
+ */
@Override
- public void configureOverflowMenu(boolean showMergeMenuOption, boolean showAddMenuOption,
- boolean showHoldMenuOption, boolean showSwapMenuOption,
- boolean showManageConferenceVideoCallOption) {
- if (mOverflowPopup == null) {
- final ContextThemeWrapper contextWrapper = new ContextThemeWrapper(getActivity(),
- R.style.InCallPopupMenuStyle);
- mOverflowPopup = new PopupMenu(contextWrapper, mOverflowButton);
- mOverflowPopup.getMenuInflater().inflate(R.menu.incall_overflow_menu,
- mOverflowPopup.getMenu());
+ public void updateButtonStates() {
+ View prevVisibleButton = null;
+ int prevVisibleId = -1;
+ PopupMenu menu = null;
+ int visibleCount = 0;
+ for (int i = 0; i < BUTTON_COUNT; i++) {
+ final int visibility = mButtonVisibilityMap.get(i);
+ final View button = getButtonById(i);
+ if (visibility == BUTTON_VISIBLE) {
+ visibleCount++;
+ if (visibleCount <= BUTTON_MAX_VISIBLE) {
+ button.setVisibility(View.VISIBLE);
+ prevVisibleButton = button;
+ prevVisibleId = i;
+ } else {
+ if (menu == null) {
+ menu = getPopupMenu();
+ }
+ // Collapse the current button into the overflow menu. If is the first visible
+ // button that exceeds the threshold, also collapse the previous visible button
+ // so that the total number of visible buttons will never exceed the threshold.
+ if (prevVisibleButton != null) {
+ addToOverflowMenu(prevVisibleId, prevVisibleButton, menu);
+ prevVisibleButton = null;
+ prevVisibleId = -1;
+ }
+ addToOverflowMenu(i, button, menu);
+ }
+ } else if (visibility == BUTTON_HIDDEN){
+ button.setVisibility(View.GONE);
+ }
+ }
+
+ mOverflowButton.setVisibility(menu != null ? View.VISIBLE : View.GONE);
+ if (menu != null) {
+ mOverflowPopup = menu;
mOverflowPopup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.overflow_merge_menu_item:
- getPresenter().mergeClicked();
- break;
- case R.id.overflow_add_menu_item:
- getPresenter().addCallClicked();
- break;
- case R.id.overflow_hold_menu_item:
- getPresenter().holdClicked(true /* checked */);
- break;
- case R.id.overflow_resume_menu_item:
- getPresenter().holdClicked(false /* checked */);
- break;
- case R.id.overflow_swap_menu_item:
- getPresenter().addCallClicked();
- break;
- case R.id.overflow_manage_conference_menu_item:
- onManageVideoCallConferenceClicked();
- break;
- default:
- Log.wtf(this, "onMenuItemClick: unexpected overflow menu click");
- break;
- }
+ final int id = item.getItemId();
+ getButtonById(id).performClick();
return true;
}
});
- mOverflowPopup.setOnDismissListener(new OnDismissListener() {
- @Override
- public void onDismiss(PopupMenu popupMenu) {
- popupMenu.dismiss();
- }
- });
}
-
- final Menu menu = mOverflowPopup.getMenu();
- menu.findItem(R.id.overflow_merge_menu_item).setVisible(showMergeMenuOption);
- menu.findItem(R.id.overflow_add_menu_item).setVisible(showAddMenuOption);
- menu.findItem(R.id.overflow_hold_menu_item).setVisible(
- showHoldMenuOption && !mHoldButton.isSelected());
- menu.findItem(R.id.overflow_resume_menu_item).setVisible(
- showHoldMenuOption && mHoldButton.isSelected());
- menu.findItem(R.id.overflow_swap_menu_item).setVisible(showSwapMenuOption);
- menu.findItem(R.id.overflow_manage_conference_menu_item).setVisible(
- showManageConferenceVideoCallOption);
-
- mOverflowButton.setEnabled(menu.hasVisibleItems());
}
@Override
diff --git a/InCallUI/src/com/android/incallui/CallButtonPresenter.java b/InCallUI/src/com/android/incallui/CallButtonPresenter.java
index b50827fea..cc13a87ef 100644
--- a/InCallUI/src/com/android/incallui/CallButtonPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallButtonPresenter.java
@@ -16,7 +16,8 @@
package com.android.incallui;
-import android.app.AlertDialog;
+import static com.android.incallui.CallButtonFragment.Buttons.*;
+
import android.content.Context;
import android.os.Bundle;
import android.telecom.AudioState;
@@ -46,7 +47,6 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
private Call mCall;
private boolean mAutomaticallyMuted = false;
private boolean mPreviousMuteState = false;
- private static final int BUTTON_THRESOLD_TO_DISPLAY_OVERFLOW_MENU = 5;
public CallButtonPresenter() {
}
@@ -119,7 +119,7 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
@Override
public void onDetailsChanged(Call call, android.telecom.Call.Details details) {
if (getUi() != null && Objects.equals(call, mCall)) {
- updateCallButtons(call, getUi().getContext());
+ updateButtonsState(call);
}
}
@@ -131,7 +131,7 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
@Override
public void onCanAddCallChanged(boolean canAddCall) {
if (getUi() != null && mCall != null) {
- updateCallButtons(mCall, getUi().getContext());
+ updateButtonsState(mCall);
}
}
@@ -321,7 +321,7 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
mCall.getVideoState() & ~VideoProfile.VideoState.PAUSED);
videoCall.sendSessionModifyRequest(videoProfile);
}
- getUi().setPauseVideoButton(pause);
+ getUi().setVideoPaused(pause);
}
private void updateUi(InCallState state, Call call) {
@@ -340,9 +340,9 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
return;
}
- updateCallButtons(call, ui.getContext());
+ updateButtonsState(call);
- ui.enableMute(call.can(android.telecom.Call.Details.CAPABILITY_MUTE));
+ ui.enableButton(BUTTON_MUTE, call.can(android.telecom.Call.Details.CAPABILITY_MUTE));
}
private static int toInteger(boolean b) {
@@ -353,137 +353,49 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
* Updates the buttons applicable for the UI.
*
* @param call The active call.
- * @param context The context.
*/
- private void updateCallButtons(Call call, Context context) {
- if (CallUtils.isVideoCall(call)) {
- updateVideoCallButtons(call);
- }
- updateVoiceCallButtons(call);
- }
-
- private void updateVideoCallButtons(Call call) {
- Log.v(this, "Showing buttons for video call.");
- final CallButtonUi ui = getUi();
-
- // Show all video-call-related buttons.
- ui.showSwitchCameraButton(true);
- ui.showPauseVideoButton(true);
-
- final boolean supportHold = call.can(android.telecom.Call.Details.CAPABILITY_SUPPORT_HOLD);
- final boolean enableHoldOption = call.can(android.telecom.Call.Details.CAPABILITY_HOLD);
- ui.showHoldButton(supportHold);
- ui.enableHold(enableHoldOption);
- ui.setHold(call.getState() == Call.State.ONHOLD);
- }
-
- private void updateVoiceCallButtons(Call call) {
+ private void updateButtonsState(Call call) {
Log.v(this, "Showing buttons for voice call.");
final CallButtonUi ui = getUi();
- // Hide all video-call-related buttons.
- ui.showChangeToVoiceButton(false);
- ui.showSwitchCameraButton(false);
- ui.showPauseVideoButton(false);
-
- // Show all voice-call-related buttons.
- ui.showAudioButton(true);
- ui.showDialpadButton(true);
-
- Log.v(this, "Show hold ", call.can(android.telecom.Call.Details.CAPABILITY_SUPPORT_HOLD));
- Log.v(this, "Enable hold", call.can(android.telecom.Call.Details.CAPABILITY_HOLD));
- Log.v(this, "Show merge ", call.can(
- android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE));
- Log.v(this, "Show swap ", call.can(
- android.telecom.Call.Details.CAPABILITY_SWAP_CONFERENCE));
- Log.v(this, "Show add call ", TelecomAdapter.getInstance().canAddCall());
- Log.v(this, "Show mute ", call.can(android.telecom.Call.Details.CAPABILITY_MUTE));
-
- boolean canBidiLocal =
- call.can(android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
- boolean canBidiRemote =
- call.can(android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
- Log.v(this, "Show video call local:" + canBidiLocal + ", remote: " + canBidiRemote);
-
- final boolean canAdd = TelecomAdapter.getInstance().canAddCall();
- final boolean enableHoldOption = call.can(android.telecom.Call.Details.CAPABILITY_HOLD);
- final boolean supportHold = call.can(android.telecom.Call.Details.CAPABILITY_SUPPORT_HOLD);
- final boolean isCallOnHold = call.getState() == Call.State.ONHOLD;
-
- boolean canVideoCall = canBidiLocal && canBidiRemote;
- ui.showChangeToVideoButton(canVideoCall);
-
- final boolean showMergeOption = call.can(
- android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE);
- final boolean showAddCallOption = canAdd;
- final boolean showManageVideoCallConferenceOption = call.can(
- android.telecom.Call.Details.CAPABILITY_MANAGE_CONFERENCE)
- && CallUtils.isVideoCall(call);
+ final boolean isVideo = CallUtils.isVideoCall(call);
+ // Common functionality (audio, hold, etc).
// Show either HOLD or SWAP, but not both. If neither HOLD or SWAP is available:
// (1) If the device normally can hold, show HOLD in a disabled state.
// (2) If the device doesn't have the concept of hold/swap, remove the button.
- final boolean showSwapOption = call.can(
+ final boolean showSwap = call.can(
android.telecom.Call.Details.CAPABILITY_SWAP_CONFERENCE);
- final boolean showHoldOption = !showSwapOption && (enableHoldOption || supportHold);
+ final boolean showHold = !showSwap
+ && call.can(android.telecom.Call.Details.CAPABILITY_SUPPORT_HOLD)
+ && call.can(android.telecom.Call.Details.CAPABILITY_HOLD);
+ final boolean isCallOnHold = call.getState() == Call.State.ONHOLD;
+
+ final boolean showAddCall = TelecomAdapter.getInstance().canAddCall();
+ final boolean showMerge = call.can(
+ android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE);
+ final boolean showUpgradeToVideo = !isVideo
+ && call.can(android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL)
+ && call.can(android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE);
+ final boolean showMute = call.can(android.telecom.Call.Details.CAPABILITY_MUTE);
+
+ ui.showButton(BUTTON_AUDIO, true);
+ ui.showButton(BUTTON_SWAP, showSwap);
+ ui.showButton(BUTTON_HOLD, showHold);
ui.setHold(isCallOnHold);
- //Initialize buttonCount = 2. Because speaker and dialpad these two always show in Call UI.
- int buttonCount = 2;
- buttonCount += toInteger(canVideoCall);
- buttonCount += toInteger(showAddCallOption);
- buttonCount += toInteger(showMergeOption);
- buttonCount += toInteger(showHoldOption);
- buttonCount += toInteger(showSwapOption);
- buttonCount += toInteger(call.can(android.telecom.Call.Details.CAPABILITY_MUTE));
- buttonCount += toInteger(showManageVideoCallConferenceOption);
-
- Log.v(this, "show ManageVideoCallConference: " + showManageVideoCallConferenceOption);
- Log.v(this, "No of InCall buttons: " + buttonCount + " canVideoCall: " + canVideoCall);
-
- // Show overflow menu if number of buttons is greater than 5.
- final boolean showOverflowMenu =
- buttonCount > BUTTON_THRESOLD_TO_DISPLAY_OVERFLOW_MENU;
- final boolean isVideoOverflowScenario = canVideoCall && showOverflowMenu;
- final boolean isOverflowScenario = !canVideoCall && showOverflowMenu;
-
- if (isVideoOverflowScenario) {
- ui.showHoldButton(false);
- ui.showSwapButton(false);
- ui.showAddCallButton(false);
- ui.showMergeButton(false);
- ui.showManageConferenceVideoCallButton(false);
-
- ui.configureOverflowMenu(
- showMergeOption,
- showAddCallOption /* showAddMenuOption */,
- showHoldOption && enableHoldOption /* showHoldMenuOption */,
- showSwapOption,
- showManageVideoCallConferenceOption);
- ui.showOverflowButton(true);
- } else {
- if (isOverflowScenario) {
- ui.showAddCallButton(false);
- ui.showMergeButton(false);
- ui.showManageConferenceVideoCallButton(false);
-
- ui.configureOverflowMenu(
- showMergeOption,
- showAddCallOption /* showAddMenuOption */,
- false /* showHoldMenuOption */,
- false /* showSwapMenuOption */,
- showManageVideoCallConferenceOption);
- } else {
- ui.showMergeButton(showMergeOption);
- ui.showAddCallButton(showAddCallOption);
- ui.showManageConferenceVideoCallButton(showManageVideoCallConferenceOption);
- }
+ ui.showButton(BUTTON_MUTE, showMute);
+ ui.showButton(BUTTON_ADD_CALL, showAddCall);
+ // TODO: This button is currently being used for both upgrade and downgrade scenarios.
+ // It should be split into BUTTON_DOWNGRADE_TO_VOICE AND BUTTON_UPGRADE_TO_VIDEO
+ ui.showButton(BUTTON_UPGRADE_TO_VIDEO, true);
+ ui.showButton(BUTTON_DOWNGRADE_TO_VOICE, false);
+ ui.showButton(BUTTON_SWITCH_CAMERA, isVideo);
+ ui.showButton(BUTTON_PAUSE_VIDEO, isVideo);
+ ui.showButton(BUTTON_DIALPAD, !isVideo);
+ ui.showButton(BUTTON_MERGE, showMerge);
- ui.showOverflowButton(isOverflowScenario);
- ui.showHoldButton(showHoldOption);
- ui.enableHold(enableHoldOption);
- ui.showSwapButton(showSwapOption);
- }
+ ui.updateButtonStates();
}
public void refreshMuteState() {
@@ -515,34 +427,24 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
}
public interface CallButtonUi extends Ui {
+ void showButton(int buttonId, boolean show);
+ void enableButton(int buttonId, boolean enable);
void setEnabled(boolean on);
void setMute(boolean on);
- void enableMute(boolean enabled);
- void showAudioButton(boolean show);
- void showChangeToVoiceButton(boolean show);
- void showDialpadButton(boolean show);
void setHold(boolean on);
- void showHoldButton(boolean show);
- void enableHold(boolean enabled);
- void showSwapButton(boolean show);
- void showChangeToVideoButton(boolean show);
- void enableChangeToVideoButton(boolean enable);
- void showSwitchCameraButton(boolean show);
- void setSwitchCameraButton(boolean isBackFacingCamera);
- void showAddCallButton(boolean show);
- void showManageConferenceVideoCallButton(boolean show);
- void showMergeButton(boolean show);
- void showPauseVideoButton(boolean show);
- void setPauseVideoButton(boolean isPaused);
- void showOverflowButton(boolean show);
+ void setCameraSwitched(boolean isBackFacingCamera);
+ void setVideoPaused(boolean isPaused);
+ void setAudio(int mode);
+ void setSupportedAudio(int mask);
void displayDialpad(boolean on, boolean animate);
void displayModifyCallOptions();
boolean isDialpadVisible();
- void setAudio(int mode);
- void setSupportedAudio(int mask);
- void configureOverflowMenu(boolean showMergeMenuOption, boolean showAddMenuOption,
- boolean showHoldMenuOption, boolean showSwapMenuOption,
- boolean showManageConferenceVideoCallOption);
+
+ /**
+ * Once showButton() has been called on each of the individual buttons in the UI, call
+ * this to configure the overflow menu appropriately.
+ */
+ void updateButtonStates();
Context getContext();
}
@@ -551,6 +453,6 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
if (getUi() == null) {
return;
}
- getUi().setSwitchCameraButton(!isUsingFrontFacingCamera);
+ getUi().setCameraSwitched(!isUsingFrontFacingCamera);
}
}
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index 7420ba90e..abe4607c1 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -28,6 +28,7 @@ import android.content.Context;
import android.content.res.Configuration;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.Trace;
import android.telecom.DisconnectCause;
@@ -96,6 +97,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
private View mSecondaryCallProviderInfo;
private TextView mSecondaryCallProviderLabel;
private View mSecondaryCallConferenceCallIcon;
+ private View mSecondaryCallVideoCallIcon;
private View mProgressSpinner;
private View mManageConferenceCallButton;
@@ -134,7 +136,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
mShrinkAnimationDuration = getResources().getInteger(R.integer.shrink_animation_duration);
mVideoAnimationDuration = getResources().getInteger(R.integer.video_animation_duration);
mFloatingActionButtonVerticalOffset = getResources().getDimensionPixelOffset(
- R.dimen.floating_action_bar_vertical_offset);
+ R.dimen.floating_action_button_vertical_offset);
mFabNormalDiameter = getResources().getDimensionPixelOffset(
R.dimen.end_call_floating_action_button_diameter);
mFabSmallDiameter = getResources().getDimensionPixelOffset(
@@ -156,9 +158,8 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
Trace.beginSection(TAG + " onCreate");
mTranslationOffset =
getResources().getDimensionPixelSize(R.dimen.call_card_anim_translate_y_offset);
- final View view = inflater.inflate(R.layout.call_card_fragment, container, false);
- Trace.endSection();
- return view;
+
+ return inflater.inflate(R.layout.call_card_fragment, container, false);
}
@Override
@@ -285,17 +286,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
float videoViewTranslation = 0f;
// Translate the call card to its pre-animation state.
- if (mIsLandscape) {
- float translationX = mPrimaryCallCardContainer.getWidth();
- translationX *= isLayoutRtl ? 1 : -1;
-
- mPrimaryCallCardContainer.setTranslationX(visible ? translationX : 0);
-
- if (visible) {
- videoViewTranslation = videoView.getWidth() / 2 - spaceBesideCallCard / 2;
- videoViewTranslation *= isLayoutRtl ? -1 : 1;
- }
- } else {
+ if (!mIsLandscape){
mPrimaryCallCardContainer.setTranslationY(visible ?
-mPrimaryCallCardContainer.getHeight() : 0);
@@ -458,7 +449,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
@Override
public void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
- String providerLabel, boolean isConference) {
+ String providerLabel, boolean isConference, boolean isVideoCall) {
if (show != mSecondaryCallInfo.isShown()) {
updateFabPositionForSecondaryCallInfo();
@@ -469,6 +460,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
showAndInitializeSecondaryCallInfo(hasProvider);
mSecondaryCallConferenceCallIcon.setVisibility(isConference ? View.VISIBLE : View.GONE);
+ mSecondaryCallVideoCallIcon.setVisibility(isVideoCall ? View.VISIBLE : View.GONE);
mSecondaryCallName.setText(nameIsNumber
? PhoneNumberUtils.getPhoneTtsSpannable(name)
@@ -760,6 +752,8 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
mSecondaryCallName = (TextView) getView().findViewById(R.id.secondaryCallName);
mSecondaryCallConferenceCallIcon =
getView().findViewById(R.id.secondaryCallConferenceCallIcon);
+ mSecondaryCallVideoCallIcon =
+ getView().findViewById(R.id.secondaryCallVideoCallIcon);
}
if (mSecondaryCallProviderLabel == null && hasProvider) {
@@ -849,7 +843,13 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
return;
}
- mPrimaryCallCardContainer.setBackgroundColor(themeColors.mPrimaryColor);
+ if (getResources().getBoolean(R.bool.is_layout_landscape)) {
+ final GradientDrawable drawable =
+ (GradientDrawable) mPrimaryCallCardContainer.getBackground();
+ drawable.setColor(themeColors.mPrimaryColor);
+ } else {
+ mPrimaryCallCardContainer.setBackgroundColor(themeColors.mPrimaryColor);
+ }
mCallButtonsContainer.setBackgroundColor(themeColors.mPrimaryColor);
mCurrentThemeColors = themeColors;
@@ -963,8 +963,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
mAnimatorSet.cancel();
}
- mIsLandscape = getResources().getConfiguration().orientation
- == Configuration.ORIENTATION_LANDSCAPE;
+ mIsLandscape = getResources().getBoolean(R.bool.is_layout_landscape);
final ViewGroup parent = ((ViewGroup) mPrimaryCallCardContainer.getParent());
final ViewTreeObserver observer = parent.getViewTreeObserver();
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index bd3694339..b919c6177 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -254,13 +254,11 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
}
maybeShowManageConferenceCallButton();
+ maybeShowProgressSpinner();
- final boolean enableEndCallButton = (Call.State.isConnectingOrConnected(callState)
- || callState == Call.State.DISCONNECTING) &&
- callState != Call.State.INCOMING && mPrimary != null;
// Hide the end call button instantly if we're receiving an incoming call.
- getUi().setEndCallButtonEnabled(
- enableEndCallButton, callState != Call.State.INCOMING /* animate */);
+ getUi().setEndCallButtonEnabled(shouldShowEndCallButton(mPrimary, callState),
+ callState != Call.State.INCOMING /* animate */);
}
@Override
@@ -315,6 +313,13 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
getUi().showManageConferenceCallButton(shouldShowManageConference());
}
+ private void maybeShowProgressSpinner() {
+ final boolean show = mPrimary != null && mPrimary.getSessionModificationState()
+ == Call.SessionModificationState.WAITING_FOR_RESPONSE
+ && mPrimary.getState() == Call.State.ACTIVE;
+ getUi().setProgressSpinnerVisible(show);
+ }
+
/**
* Determines if the manage conference button should be visible, based on the current primary
* call.
@@ -531,7 +536,8 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
if (mSecondary == null) {
// Clear the secondary display info.
- ui.setSecondary(false, null, false, null, null, false /* isConference */);
+ ui.setSecondary(false, null, false, null, null, false /* isConference */,
+ false /* isVideoCall */);
return;
}
@@ -542,7 +548,8 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
false /* nameIsNumber */,
null /* label */,
getCallProviderLabel(mSecondary),
- true /* isConference */);
+ true /* isConference */,
+ mSecondary.isVideoCall(mContext));
} else if (mSecondaryContactInfo != null) {
Log.d(TAG, "updateSecondaryDisplayInfo() " + mSecondaryContactInfo);
String name = getNameForCall(mSecondaryContactInfo);
@@ -553,10 +560,12 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
nameIsNumber,
mSecondaryContactInfo.label,
getCallProviderLabel(mSecondary),
- false /* isConference */);
+ false /* isConference */,
+ mSecondary.isVideoCall(mContext));
} else {
// Clear the secondary display info.
- ui.setSecondary(false, null, false, null, null, false /* isConference */);
+ ui.setSecondary(false, null, false, null, null, false /* isConference */,
+ false /* isVideoCall */);
}
}
@@ -736,13 +745,27 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
return photo;
}
+ private boolean shouldShowEndCallButton(Call primary, int callState) {
+ if (primary == null) {
+ return false;
+ }
+ if (!Call.State.isConnectingOrConnected(callState) || callState == Call.State.INCOMING) {
+ return false;
+ }
+ if (mPrimary.getSessionModificationState()
+ == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
+ return false;
+ }
+ return true;
+ }
+
public interface CallCardUi extends Ui {
void setVisible(boolean on);
void setCallCardVisible(boolean visible);
void setPrimary(String number, String name, boolean nameIsNumber, String label,
Drawable photo, boolean isSipCall);
void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
- String providerLabel, boolean isConference);
+ String providerLabel, boolean isConference, boolean isVideoCall);
void setCallState(int state, int videoState, int sessionModificationState,
DisconnectCause disconnectCause, String connectionLabel,
Drawable connectionIcon, String gatewayNumber, boolean isWifi);
diff --git a/InCallUI/src/com/android/incallui/DialpadFragment.java b/InCallUI/src/com/android/incallui/DialpadFragment.java
index 90610a82d..f185c54bc 100644
--- a/InCallUI/src/com/android/incallui/DialpadFragment.java
+++ b/InCallUI/src/com/android/incallui/DialpadFragment.java
@@ -422,7 +422,7 @@ public class DialpadFragment extends BaseFragment<DialpadPresenter, DialpadPrese
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View parent = inflater.inflate(
- com.android.incallui.R.layout.incall_dialpad_fragment, container, false);
+ R.layout.incall_dialpad_fragment, container, false);
mDialpadView = (DialpadView) parent.findViewById(R.id.dialpad_view);
mDialpadView.setCanDigitsBeEdited(false);
mDialpadView.setBackgroundResource(R.color.incall_dialpad_background);
diff --git a/InCallUI/src/com/android/incallui/GlowPadWrapper.java b/InCallUI/src/com/android/incallui/GlowPadWrapper.java
index 584ce65de..58a5f30ea 100644
--- a/InCallUI/src/com/android/incallui/GlowPadWrapper.java
+++ b/InCallUI/src/com/android/incallui/GlowPadWrapper.java
@@ -128,14 +128,6 @@ public class GlowPadWrapper extends GlowPadView implements GlowPadView.OnTrigger
mAnswerListener.onAnswer(VideoProfile.VideoState.BIDIRECTIONAL, getContext());
mTargetTriggered = true;
break;
- case R.drawable.ic_lockscreen_answer_tx_video:
- mAnswerListener.onAnswer(VideoProfile.VideoState.TX_ENABLED, getContext());
- mTargetTriggered = true;
- break;
- case R.drawable.ic_lockscreen_answer_rx_video:
- mAnswerListener.onAnswer(VideoProfile.VideoState.RX_ENABLED, getContext());
- mTargetTriggered = true;
- break;
case R.drawable.ic_toolbar_video_off:
InCallPresenter.getInstance().declineUpgradeRequest(getContext());
mTargetTriggered = true;
diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java
index 1283177d6..5ecb96e3f 100644
--- a/InCallUI/src/com/android/incallui/InCallActivity.java
+++ b/InCallUI/src/com/android/incallui/InCallActivity.java
@@ -473,16 +473,11 @@ public class InCallActivity extends Activity implements FragmentDisplayManager {
return false;
}
- @Override
- public void onConfigurationChanged(Configuration config) {
- InCallPresenter.getInstance().getProximitySensor().onConfigurationChanged(config);
- Log.d(this, "onConfigurationChanged "+config.orientation);
-
- doOrientationChanged(config.orientation);
- super.onConfigurationChanged(config);
- }
-
-
+ /**
+ * Handles changes in device orientation.
+ *
+ * @param orientation The new device orientation.
+ */
private void doOrientationChanged(int orientation) {
Log.d(this, "doOrientationChanged prevOrientation=" + sCurrentOrientation +
" newOrientation=" + orientation);
diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java
index fdf193318..d5aa0e500 100644
--- a/InCallUI/src/com/android/incallui/InCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/InCallPresenter.java
@@ -20,6 +20,7 @@ import android.app.FragmentManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.res.Resources;
import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
@@ -179,7 +180,7 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener,
/**
* When configuration changes Android kills the current activity and starts a new one.
- * The flag is used to check if full clean up is necessary (activity is stopped and new
+ * The flag is used to check if full clean up is necessary (activity is stopped and new
* activity won't be started), or if a new activity will be started right after the current one
* is destroyed, and therefore no need in release all resources.
*/
@@ -1446,7 +1447,13 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener,
return;
}
- mInCallActivity.getWindow().setStatusBarColor(mThemeColors.mSecondaryColor);
+ final Resources resources = mInCallActivity.getResources();
+ if (resources.getBoolean(R.bool.is_layout_landscape)) {
+ mInCallActivity.getWindow().setStatusBarColor(
+ resources.getColor(R.color.statusbar_background_color));
+ } else {
+ mInCallActivity.getWindow().setStatusBarColor(mThemeColors.mSecondaryColor);
+ }
}
/**
diff --git a/InCallUI/src/com/android/incallui/InCallVideoCallListener.java b/InCallUI/src/com/android/incallui/InCallVideoCallListener.java
index df9dfdce7..741b8d614 100644
--- a/InCallUI/src/com/android/incallui/InCallVideoCallListener.java
+++ b/InCallUI/src/com/android/incallui/InCallVideoCallListener.java
@@ -87,8 +87,10 @@ public class InCallVideoCallListener extends VideoCall.Listener {
boolean isVideoCall = VideoProfile.VideoState.isVideo(responseProfile.getVideoState());
if (modifySucceeded && isVideoCall) {
InCallVideoCallListenerNotifier.getInstance().upgradeToVideoSuccess(mCall);
- } else if (!modifySucceeded) {
+ } else if (!modifySucceeded && isVideoCall) {
InCallVideoCallListenerNotifier.getInstance().upgradeToVideoFail(status, mCall);
+ } else if (modifySucceeded && !isVideoCall) {
+ InCallVideoCallListenerNotifier.getInstance().downgradeToAudio(mCall);
}
} else {
Log.d(this, "onSessionModifyResponseReceived request and response Profiles are null");
diff --git a/InCallUI/src/com/android/incallui/VideoCallFragment.java b/InCallUI/src/com/android/incallui/VideoCallFragment.java
index d0ef13a50..fb29c9ce6 100644
--- a/InCallUI/src/com/android/incallui/VideoCallFragment.java
+++ b/InCallUI/src/com/android/incallui/VideoCallFragment.java
@@ -19,6 +19,7 @@ package com.android.incallui;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.SurfaceTexture;
import android.os.Bundle;
@@ -90,11 +91,6 @@ public class VideoCallFragment extends BaseFragment<VideoCallPresenter,
private View mVideoViews;
/**
- * {@code True} when the entering the activity again after a restart due to orientation change.
- */
- private boolean mIsActivityRestart;
-
- /**
* {@code True} when the layout of the activity has been completed.
*/
private boolean mIsLayoutComplete = false;
@@ -404,12 +400,20 @@ public class VideoCallFragment extends BaseFragment<VideoCallPresenter,
Log.e(this, "onClick: Presenter is null.");
}
}
+
+ /**
+ * Returns the dimensions of the surface.
+ *
+ * @return The dimensions of the surface.
+ */
+ public Point getSurfaceDimensions() {
+ return new Point(mWidth, mHeight);
+ }
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mIsActivityRestart = sVideoSurfacesInUse;
}
/**
@@ -421,21 +425,12 @@ public class VideoCallFragment extends BaseFragment<VideoCallPresenter,
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- mIsLandscape = getResources().getConfiguration().orientation
- == Configuration.ORIENTATION_LANDSCAPE;
+ mIsLandscape = getResources().getBoolean(R.bool.is_layout_landscape);
Log.d(this, "onActivityCreated: IsLandscape=" + mIsLandscape);
getPresenter().init(getActivity());
}
- /**
- * Handles creation of the fragment view.
- *
- * @param inflater The inflater.
- * @param container The view group containing the fragment.
- * @param savedInstanceState The saved instance state.
- * @return
- */
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -447,36 +442,15 @@ public class VideoCallFragment extends BaseFragment<VideoCallPresenter,
}
/**
- * Centers the display view vertically for portrait orientation, and horizontally for
- * lanscape orientations. The view is centered within the available space not occupied by
- * the call card.
+ * Centers the display view vertically for portrait orientations. The view is centered within
+ * the available space not occupied by the call card. This is a no-op for landscape mode.
*
* @param displayVideo The video view to center.
*/
private void centerDisplayView(View displayVideo) {
- // In a lansdcape layout we need to ensure we horizontally center the view based on whether
- // the layout is left-to-right or right-to-left.
- // In a left-to-right locale, the space for the video view is to the right of the call card
- // so we need to translate it in the +X direction.
- // In a right-to-left locale, the space for the video view is to the left of the call card
- // so we need to translate it in the -X direction.
- final boolean isLayoutRtl = InCallPresenter.isRtl();
-
- ViewGroup.LayoutParams params = displayVideo.getLayoutParams();
- float spaceBesideCallCard = InCallPresenter.getInstance().getSpaceBesideCallCard();
- Log.d(this, "centerDisplayView: IsLandscape= " + mIsLandscape + " Layout width: " +
- params.width + " height: " + params.height + " spaceBesideCallCard: "
- + spaceBesideCallCard);
- if (mIsLandscape) {
- float videoViewTranslation = params.width / 2
- - spaceBesideCallCard / 2;
- if (isLayoutRtl) {
- displayVideo.setTranslationX(-videoViewTranslation);
- } else {
- displayVideo.setTranslationX(videoViewTranslation);
- }
- } else {
- float videoViewTranslation = params.height / 2
+ if (!mIsLandscape) {
+ float spaceBesideCallCard = InCallPresenter.getInstance().getSpaceBesideCallCard();
+ float videoViewTranslation = displayVideo.getHeight() / 2
- spaceBesideCallCard / 2;
displayVideo.setTranslationY(videoViewTranslation);
}
@@ -701,12 +675,6 @@ public class VideoCallFragment extends BaseFragment<VideoCallPresenter,
}
}
- @Override
- public boolean isActivityRestart() {
- Log.d(this, "isActivityRestart " + mIsActivityRestart);
- return mIsActivityRestart;
- }
-
/**
* @return {@code True} if the display video surface has been created.
*/
@@ -767,12 +735,12 @@ public class VideoCallFragment extends BaseFragment<VideoCallPresenter,
params.height = height;
preview.setLayoutParams(params);
- int rotation = InCallPresenter.toRotationAngle(getCurrentRotation());
- int rotationAngle = 360 - rotation;
- preview.setRotation(rotationAngle);
- Log.d(this, "setPreviewSize: rotation=" + rotation +
- " rotationAngle=" + rotationAngle);
-
+ // The width and height are interchanged outside of this method based on the current
+ // orientation, so we can transform using "width", which will be either the width or
+ // the height.
+ Matrix transform = new Matrix();
+ transform.setScale(-1, 1, width/2, 0);
+ preview.setTransform(transform);
}
}
@@ -879,6 +847,19 @@ public class VideoCallFragment extends BaseFragment<VideoCallPresenter,
}
/**
+ * Determines the size of the preview surface.
+ *
+ * @return {@link Point} specifying the width and height of the preview surface.
+ */
+ @Override
+ public Point getPreviewSize() {
+ if (sPreviewSurface == null) {
+ return null;
+ }
+ return sPreviewSurface.getSurfaceDimensions();
+ }
+
+ /**
* Inflates the {@link ViewStub} containing the incoming and outgoing surfaces, if necessary,
* and creates {@link VideoCallSurface} instances to track the surfaces.
*/
diff --git a/InCallUI/src/com/android/incallui/VideoCallPresenter.java b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
index 43eef4b50..56f312f63 100644
--- a/InCallUI/src/com/android/incallui/VideoCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
@@ -65,7 +65,7 @@ import android.os.SystemProperties;
* When downgrading to an audio-only video state, the {@code VideoCallPresenter} nulls both
* surfaces.
*/
-public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi> implements
+public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi> implements
IncomingCallListener, InCallOrientationListener, InCallStateListener,
InCallDetailsListener, SurfaceChangeListener, VideoEventListener,
InCallVideoCallListenerNotifier.SessionModificationListener {
@@ -167,7 +167,6 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
*/
private int mCurrentCallSubstate;
-
/** Handler which resets request state to NO_REQUEST after an interval. */
private Handler mSessionModificationResetHandler;
private static final long SESSION_MODIFICATION_RESET_DELAY_MS = 3000;
@@ -339,11 +338,11 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
toggleFullScreen();
}
-
/**
* Handles incoming calls.
*
- * @param state The in call state.
+ * @param oldState The old in call state.
+ * @param newState The new in call state.
* @param call The call.
*/
@Override
@@ -414,12 +413,14 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
+ " hasVideoStateChanged=" +
hasVideoStateChanged + " isVideoMode=" + isVideoMode());
- if (!hasVideoStateChanged) { return;}
+ if (!hasVideoStateChanged) {
+ return;
+ }
updateCameraSelection(call);
if (isVideoCall) {
- enterVideoMode(call.getVideoCall(), call.getVideoState());
+ enterVideoMode(call);
} else if (isVideoMode()) {
exitVideoMode();
}
@@ -447,6 +448,9 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
if (!Objects.equals(prevCameraId, newCameraId) && CallUtils.isActiveVideoCall(call)) {
enableCamera(call.getVideoCall(), true);
}
+
+ // Make sure we hide or show the video UI if needed.
+ showVideoUi(call.getVideoState(), call.getState());
}
private void checkForCallSubstateChange(Call call) {
@@ -487,7 +491,7 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
Log.d(this, "onPrimaryCallChanged: Entering video mode...");
updateCameraSelection(newPrimaryCall);
- enterVideoMode(newPrimaryCall.getVideoCall(), newPrimaryCall.getVideoState());
+ enterVideoMode(newPrimaryCall);
}
}
@@ -538,6 +542,11 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
checkForVideoCallChange(call);
checkForVideoStateChange(call);
checkForCallStateChange(call);
+ checkForOrientationAllowedChange(call);
+ }
+
+ private void checkForOrientationAllowedChange(Call call) {
+ InCallPresenter.getInstance().setInCallAllowsOrientationChange(CallUtils.isVideoCall(call));
}
/**
@@ -577,7 +586,7 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
}
if (CallUtils.isVideoCall(call) && hasChanged) {
- enterVideoMode(call.getVideoCall(), call.getVideoState());
+ enterVideoMode(call);
}
}
@@ -594,7 +603,10 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
* Enters video mode by showing the video surfaces and making other adjustments (eg. audio).
* TODO(vt): Need to adjust size and orientation of preview surface here.
*/
- private void enterVideoMode(VideoCall videoCall, int newVideoState) {
+ private void enterVideoMode(Call call) {
+ VideoCall videoCall = call.getVideoCall();
+ int newVideoState = call.getVideoState();
+
Log.d(this, "enterVideoMode videoCall= " + videoCall + " videoState: " + newVideoState);
VideoCallUi ui = getUi();
if (ui == null) {
@@ -602,8 +614,7 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
return;
}
- showVideoUi(newVideoState);
- InCallPresenter.getInstance().setInCallAllowsOrientationChange(true);
+ showVideoUi(newVideoState, call.getState());
// Communicate the current camera to telephony and make a request for the camera
// capabilities.
@@ -693,9 +704,7 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
private void exitVideoMode() {
Log.d(this, "exitVideoMode");
- InCallPresenter.getInstance().setInCallAllowsOrientationChange(false);
-
- showVideoUi(VideoProfile.VideoState.AUDIO_ONLY);
+ showVideoUi(VideoProfile.VideoState.AUDIO_ONLY, Call.State.ACTIVE);
enableCamera(mVideoCall, false);
Log.d(this, "exitVideoMode mIsFullScreen: " + mIsFullScreen);
@@ -707,21 +716,28 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
}
/**
- * Show video Ui depends on video state.
+ * Based on the current {@link VideoProfile.VideoState} and {@code CallState}, show or hide the
+ * incoming and outgoing video surfaces. The outgoing video surface is shown any time video
+ * is transmitting. The incoming video surface is shown whenever the video is un-paused and
+ * active.
+ *
+ * @param videoState The video state.
+ * @param callState The call state.
*/
- private void showVideoUi(int videoState) {
+ private void showVideoUi(int videoState, int callState) {
VideoCallUi ui = getUi();
if (ui == null) {
Log.e(this, "showVideoUi, VideoCallUi is null returning");
return;
}
-
+ boolean isPaused = VideoProfile.VideoState.isPaused(videoState);
+ boolean isCallActive = callState == Call.State.ACTIVE;
if (VideoProfile.VideoState.isBidirectional(videoState)) {
- ui.showVideoViews(true, true);
+ ui.showVideoViews(true, !isPaused && isCallActive);
} else if (VideoProfile.VideoState.isTransmissionEnabled(videoState)) {
ui.showVideoViews(true, false);
} else if (VideoProfile.VideoState.isReceptionEnabled(videoState)) {
- ui.showVideoViews(false, true);
+ ui.showVideoViews(false, !isPaused && isCallActive);
} else {
ui.hideVideoUi();
}
@@ -818,6 +834,29 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
}
mPreviewSurfaceState = PreviewSurfaceState.CAPABILITIES_RECEIVED;
+ changePreviewDimensions(width, height);
+
+ // Check if the preview surface is ready yet; if it is, set it on the {@code VideoCall}.
+ // If it not yet ready, it will be set when when creation completes.
+ if (ui.isPreviewVideoSurfaceCreated()) {
+ mPreviewSurfaceState = PreviewSurfaceState.SURFACE_SET;
+ mVideoCall.setPreviewSurface(ui.getPreviewVideoSurface());
+ }
+ }
+
+ /**
+ * Changes the dimensions of the preview surface.
+ *
+ * @param width The new width.
+ * @param height The new height.
+ */
+ private void changePreviewDimensions(int width, int height) {
+ VideoCallUi ui = getUi();
+ if (ui == null) {
+ return;
+ }
+
+ // Resize the surface used to display the preview video
ui.setPreviewSurfaceSize(width, height);
// Configure the preview surface to the correct aspect ratio.
@@ -825,14 +864,10 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
if (width > 0 && height > 0) {
aspectRatio = (float) width / (float) height;
}
- setPreviewSize(mDeviceOrientation, aspectRatio);
- // Check if the preview surface is ready yet; if it is, set it on the {@code VideoCall}.
- // If it not yet ready, it will be set when when creation completes.
- if (ui.isPreviewVideoSurfaceCreated()) {
- mPreviewSurfaceState = PreviewSurfaceState.SURFACE_SET;
- mVideoCall.setPreviewSurface(ui.getPreviewVideoSurface());
- }
+ // Resize the textureview housing the preview video and rotate it appropriately based on
+ // the device orientation
+ setPreviewSize(mDeviceOrientation, aspectRatio);
}
/**
@@ -874,8 +909,11 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
*/
@Override
public void onDeviceOrientationChanged(int orientation) {
- Log.d(this, "onDeviceOrientationChanged: orientation=" + orientation);
mDeviceOrientation = orientation;
+ Point previewDimensions = getUi().getPreviewSize();
+ Log.d(this, "onDeviceOrientationChanged: orientation=" + orientation + " size: "
+ + previewDimensions);
+ changePreviewDimensions(previewDimensions.x, previewDimensions.y);
}
@Override
@@ -939,6 +977,7 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
@Override
public void onDowngradeToAudio(Call call) {
+ call.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
// exit video mode
exitVideoMode();
}
@@ -1102,8 +1141,8 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
void setCallDataUsage(Context context, long dataUsage);
void displayCallSessionEvent(int event);
Point getScreenSize();
+ Point getPreviewSize();
void cleanupSurfaces();
- boolean isActivityRestart();
void showCallSubstateChanged(int callSubstate);
}
}
diff --git a/InCallUI/src/com/android/incallui/VideoPauseController.java b/InCallUI/src/com/android/incallui/VideoPauseController.java
index 727780e8f..4b8ad7562 100644
--- a/InCallUI/src/com/android/incallui/VideoPauseController.java
+++ b/InCallUI/src/com/android/incallui/VideoPauseController.java
@@ -38,12 +38,16 @@ import com.android.incallui.InCallVideoCallListenerNotifier.SessionModificationL
import com.android.internal.util.Preconditions;
/**
- * The class is responsible for generating video pause/resume request.
+ * This class is responsible for generating video pause/resume requests when the InCall UI is sent
+ * to the background and subsequently brought back to the foreground.
*/
class VideoPauseController implements InCallStateListener, IncomingCallListener,
SessionModificationListener {
- private static final String TAG = "VideoCallPauseController:";
+ private static final String TAG = "VideoPauseController:";
+ /**
+ * Keeps track of the current active/foreground call.
+ */
private class CallContext {
public CallContext(Call call) {
Preconditions.checkNotNull(call);
@@ -53,7 +57,6 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
public void update(Call call) {
mCall = Preconditions.checkNotNull(call);
mState = call.getState();
- mId = call.getId();
mVideoState = call.getVideoState();
}
@@ -61,17 +64,13 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
return mState;
}
- public String getId() {
- return mId;
- }
-
public int getVideoState() {
return mVideoState;
}
public String toString() {
- return String.format("CallContext {CallId=%s, State=%s, VideoState=",
- mId, mState, mVideoState);
+ return String.format("CallContext {CallId=%s, State=%s, VideoState=%d}",
+ mCall.getId(), mState, mVideoState);
}
public Call getCall() {
@@ -79,7 +78,6 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
}
private int mState = State.INVALID;
- private String mId;
private int mVideoState;
private Call mCall;
}
@@ -87,27 +85,21 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
private InCallPresenter mInCallPresenter;
private static VideoPauseController sVideoPauseController;
- private CallContext mPrimaryCallContext = null; // Context of primary call, if any.
- private boolean mIsInBackground = false; // True if UI is not visible, false otherwise.
- private int mVideoPauseMode = VIDEO_PAUSE_MODE_DISABLED;
+ /**
+ * The current call context, if applicable.
+ */
+ private CallContext mPrimaryCallContext = null;
/**
- * Stores current video pause mode.
- * 0 - Video Pause is disabled.
- * 1 - Video Pause is enabled.
+ * Tracks whether the application is in the background. {@code True} if the application is in
+ * the background, {@code false} otherwise.
*/
- private static final String PROPERTY_VIDEO_PAUSE_MODE = "persist.radio.videopause.mode";
- private static int VIDEO_PAUSE_MODE_DISABLED = 0;
- private static int VIDEO_PAUSE_MODE_ENABLED = 1;
-
- private VideoPauseController() {
- mVideoPauseMode = SystemProperties.getInt(PROPERTY_VIDEO_PAUSE_MODE,
- VIDEO_PAUSE_MODE_DISABLED);
- if (mVideoPauseMode != VIDEO_PAUSE_MODE_ENABLED) { // Validate the mode before using.
- mVideoPauseMode = VIDEO_PAUSE_MODE_DISABLED;
- }
- }
+ private boolean mIsInBackground = false;
+ /**
+ * Singleton accessor for the {@link VideoPauseController}.
+ * @return Singleton instance of the {@link VideoPauseController}.
+ */
/*package*/
static synchronized VideoPauseController getInstance() {
if (sVideoPauseController == null) {
@@ -116,23 +108,25 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
return sVideoPauseController;
}
+ /**
+ * Configures the {@link VideoPauseController} to listen to call events. Configured via the
+ * {@link com.android.incallui.InCallPresenter}.
+ *
+ * @param inCallPresenter The {@link com.android.incallui.InCallPresenter}.
+ */
public void setUp(InCallPresenter inCallPresenter) {
- if (!isVideoPausedEnabled()) {
- return;
- }
-
- log("setUp...");
+ log("setUp");
mInCallPresenter = Preconditions.checkNotNull(inCallPresenter);
mInCallPresenter.addListener(this);
mInCallPresenter.addIncomingCallListener(this);
InCallVideoCallListenerNotifier.getInstance().addSessionModificationListener(this);
}
+ /**
+ * Cleans up the {@link VideoPauseController} by removing all listeners and clearing its
+ * internal state. Called from {@link com.android.incallui.InCallPresenter}.
+ */
public void tearDown() {
- if (!isVideoPausedEnabled()) {
- return;
- }
-
log("tearDown...");
InCallVideoCallListenerNotifier.getInstance().removeSessionModificationListener(this);
mInCallPresenter.removeListener(this);
@@ -140,6 +134,9 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
clear();
}
+ /**
+ * Clears the internal state for the {@link VideoPauseController}.
+ */
private void clear() {
mInCallPresenter = null;
mPrimaryCallContext = null;
@@ -147,8 +144,11 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
}
/**
- * The function gets called when call state changes.
- * @param state Phone state.
+ * Handles changes in the {@link InCallState}. Triggers pause and resumption of video for the
+ * current foreground call.
+ *
+ * @param oldState The previous {@link InCallState}.
+ * @param newState The current {@link InCallState}.
* @param callList List of current call.
*/
@Override
@@ -179,7 +179,7 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
return;
}
- if (isOutgoing(mPrimaryCallContext) && canVideoPause && mIsInBackground) {
+ if (isDialing(mPrimaryCallContext) && canVideoPause && mIsInBackground) {
// Bring UI to foreground if outgoing request becomes active while UI is in
// background.
bringToForeground();
@@ -192,6 +192,15 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
updatePrimaryCallContext(call);
}
+ /**
+ * Handles a change to the primary call.
+ * <p>
+ * Reject incoming or hangup dialing call: Where the previous call was an incoming call or a
+ * call in dialing state, resume the new primary call.
+ * Call swap: Where the new primary call is incoming, pause video on the previous primary call.
+ *
+ * @param call The new primary call.
+ */
private void onPrimaryCallChanged(Call call) {
log("onPrimaryCallChanged: New call = " + call);
log("onPrimaryCallChanged: Old call = " + mPrimaryCallContext);
@@ -200,25 +209,26 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
Preconditions.checkState(!areSame(call, mPrimaryCallContext));
final boolean canVideoPause = CallUtils.canVideoPause(call);
- if (isWaitingCall(mPrimaryCallContext) && canVideoPause && !mIsInBackground) {
- // Send resume request for the active call, if user rejects incoming
- // call and UI is in foreground.
+ if ((isIncomingCall(mPrimaryCallContext) || isDialing(mPrimaryCallContext))
+ && canVideoPause && !mIsInBackground) {
+ // Send resume request for the active call, if user rejects incoming call or ends
+ // dialing call and UI is in the foreground.
sendRequest(call, true);
- } else if (isWaitingCall(call) && canVideoPause(mPrimaryCallContext)) {
+ } else if (isIncomingCall(call) && canVideoPause(mPrimaryCallContext)) {
// Send pause request if there is an active video call, and we just received a new
// incoming call.
sendRequest(mPrimaryCallContext.getCall(), false);
- } else if (isOutgoing(mPrimaryCallContext) && canVideoPause && !mIsInBackground) {
- // Send resume request for the active call, if user ends outgoing call
- // and UI is in foreground.
- sendRequest(call, true);
}
updatePrimaryCallContext(call);
}
/**
- * The function gets called when InCallUI receives a new incoming call.
+ * Handles new incoming calls by triggering a change in the primary call.
+ *
+ * @param oldState the old {@link InCallState}.
+ * @param newState the new {@link InCallState}.
+ * @param call the incoming call.
*/
@Override
public void onIncomingCall(InCallState oldState, InCallState newState, Call call) {
@@ -231,6 +241,11 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
onPrimaryCallChanged(call);
}
+ /**
+ * Caches a reference to the primary call and stores its previous state.
+ *
+ * @param call The new primary call.
+ */
private void updatePrimaryCallContext(Call call) {
if (call == null) {
mPrimaryCallContext = null;
@@ -246,43 +261,67 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
* @param showing true if UI is in the foreground, false otherwise.
*/
public void onUiShowing(boolean showing) {
- if (!isVideoPausedEnabled() || mInCallPresenter == null) {
+ // Only send pause/unpause requests if we are in the INCALL state.
+ if (mInCallPresenter == null || mInCallPresenter.getInCallState() != InCallState.INCALL) {
return;
}
- final boolean notify = mInCallPresenter.getInCallState() == InCallState.INCALL;
if (showing) {
- onResume(notify);
+ onResume();
} else {
- onPause(notify);
+ onPause();
}
}
+ /**
+ * Handles requests to upgrade to video.
+ *
+ * @param call The call the request was received for.
+ * @param videoState The video state that the request wants to upgrade to.
+ */
@Override
public void onUpgradeToVideoRequest(Call call, int videoState) {
+ // Not used.
}
+ /**
+ * Handles successful upgrades to video.
+ * @param call The call the request was successful for.
+ */
@Override
public void onUpgradeToVideoSuccess(Call call) {
+ // Not used.
}
+ /**
+ * Handles a failure to upgrade a call to video.
+ *
+ * @param status The failure status.
+ * @param call The call the request was successful for.
+ */
@Override
public void onUpgradeToVideoFail(int status, Call call) {
// TODO (ims-vt) Automatically bring in call ui to foreground.
}
+ /**
+ * Handles a downgrade of a call to audio-only.
+ *
+ * @param call The call which was downgraded to audio-only.
+ */
@Override
public void onDowngradeToAudio(Call call) {
}
/**
- * Called when UI becomes visible. This will send resume request for current video call, if any.
+ * Called when UI is brought to the foreground. Sends a session modification request to resume
+ * the outgoing video.
*/
- private void onResume(boolean notify) {
- log("onResume: notify=" + notify);
+ private void onResume() {
+ log("onResume");
mIsInBackground = false;
- if (canVideoPause(mPrimaryCallContext) && notify) {
+ if (canVideoPause(mPrimaryCallContext)) {
sendRequest(mPrimaryCallContext.getCall(), true);
} else {
log("onResume. Ignoring...");
@@ -290,13 +329,14 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
}
/**
- * Called when UI becomes invisible. This will send pause request for current video call, if any.
+ * Called when UI is sent to the background. Sends a session modification request to pause the
+ * outgoing video.
*/
- private void onPause(boolean notify) {
- log("onPause: notify=" + notify);
+ private void onPause() {
+ log("onPause");
mIsInBackground = true;
- if (canVideoPause(mPrimaryCallContext) && notify) {
+ if (canVideoPause(mPrimaryCallContext)) {
sendRequest(mPrimaryCallContext.getCall(), false);
} else {
log("onPause, Ignoring...");
@@ -314,75 +354,118 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
/**
* Sends Pause/Resume request.
+ *
* @param call Call to be paused/resumed.
* @param resume If true resume request will be sent, otherwise pause request.
*/
private void sendRequest(Call call, boolean resume) {
+ // Check if this call supports pause/un-pause.
+ if (!call.can(android.telecom.Call.Details.CAPABILITY_CAN_PAUSE_VIDEO)) {
+ return;
+ }
+
if (resume) {
log("sending resume request, call=" + call);
- call.getVideoCall().sendSessionModifyRequest(CallUtils.makeVideoUnPauseProfile(call));
+ call.getVideoCall()
+ .sendSessionModifyRequest(CallUtils.makeVideoUnPauseProfile(call));
} else {
log("sending pause request, call=" + call);
call.getVideoCall().sendSessionModifyRequest(CallUtils.makeVideoPauseProfile(call));
}
}
- private boolean isVideoPausedEnabled() {
- return mVideoPauseMode != VIDEO_PAUSE_MODE_DISABLED;
- }
-
+ /**
+ * Determines if a given call is the same one stored in a {@link CallContext}.
+ *
+ * @param call The call.
+ * @param callContext The call context.
+ * @return {@code true} if the {@link Call} is the same as the one referenced in the
+ * {@link CallContext}.
+ */
private static boolean areSame(Call call, CallContext callContext) {
if (call == null && callContext == null) {
return true;
} else if (call == null || callContext == null) {
return false;
}
- return call.getId().equals(callContext.getId());
- }
-
- private static boolean areSame(CallContext callContext, Call call) {
- return areSame(call, callContext);
+ return call.equals(callContext.getCall());
}
+ /**
+ * Determines if a video call can be paused. Only a video call which is active can be paused.
+ *
+ * @param callContext The call context to check.
+ * @return {@code true} if the call is an active video call.
+ */
private static boolean canVideoPause(CallContext callContext) {
return isVideoCall(callContext) && callContext.getState() == Call.State.ACTIVE;
}
+ /**
+ * Determines if a call referenced by a {@link CallContext} is a video call.
+ *
+ * @param callContext The call context.
+ * @return {@code true} if the call is a video call, {@code false} otherwise.
+ */
private static boolean isVideoCall(CallContext callContext) {
return callContext != null && VideoProfile.VideoState.isVideo(callContext.getVideoState());
}
/**
- * Returns true if call is in incoming/waiting state, false otherwise.
+ * Determines if call is in incoming/waiting state.
+ *
+ * @param call The call context.
+ * @return {@code true} if the call is in incoming or waiting state, {@code false} otherwise.
*/
- private static boolean isWaitingCall(CallContext call) {
- return call != null && (call.getState() == Call.State.CALL_WAITING
- || call.getState() == Call.State.INCOMING);
+ private static boolean isIncomingCall(CallContext call) {
+ return call != null && isIncomingCall(call.getCall());
}
- private static boolean isWaitingCall(Call call) {
+ /**
+ * Determines if a call is in incoming/waiting state.
+ *
+ * @param call The call.
+ * @return {@code true} if the call is in incoming or waiting state, {@code false} otherwise.
+ */
+ private static boolean isIncomingCall(Call call) {
return call != null && (call.getState() == Call.State.CALL_WAITING
|| call.getState() == Call.State.INCOMING);
}
/**
- * Returns true if the call is outgoing, false otherwise
+ * Determines if a call is dialing.
+ *
+ * @param call The call context.
+ * @return {@code true} if the call is dialing, {@code false} otherwise.
*/
- private static boolean isOutgoing(CallContext call) {
+ private static boolean isDialing(CallContext call) {
return call != null && Call.State.isDialing(call.getState());
}
/**
- * Returns true if the call is on hold, false otherwise
+ * Determines if a call is holding.
+ *
+ * @param call The call context.
+ * @return {@code true} if the call is holding, {@code false} otherwise.
*/
private static boolean isHolding(CallContext call) {
return call != null && call.getState() == Call.State.ONHOLD;
}
+ /**
+ * Logs a debug message.
+ *
+ * @param msg The message.
+ */
private void log(String msg) {
Log.d(this, TAG + msg);
}
+ /**
+ * Logs an error message.
+ *
+ * @param msg The message.
+ */
private void loge(String msg) {
Log.e(this, TAG + msg);
}