summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVinit Deshpande <vinitd@google.com>2015-04-16 02:36:02 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-04-16 02:38:21 +0000
commit2be016ffdd6e28cfa190971c4a0897457d2e216b (patch)
tree609852deffc666a424ccdac00f8db85694480aca
parent5b11e0e5d8cbf3fd2b66ce47f5097cf5e6d68aa7 (diff)
parentfddbfbcd6cc080dc706a851374c4cc8bcbf61f81 (diff)
Merge changes from topic 'mwd-merge-041515'
* changes: Fix build issues after the merge am b04d61a..697f674 from mirror-m-wireless-internal-release
-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/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
27 files changed, 600 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/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..43431c73c 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_TX)
+ && call.can(android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_RX);
+ 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 bddeea351..535ba3bf0 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 c89b3b091..dd47c7f4a 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.google.common.base.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);
}