summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Gunn <tgunn@google.com>2015-05-05 12:22:38 -0700
committerTyler Gunn <tgunn@google.com>2015-05-06 15:59:03 +0000
commitb0cf72eaa629a438a939dec34b2f7436416e045e (patch)
treee140bf0926cbd485f0a55a93e989415049dbd023
parent4e706622923b412228d2537e521b926b9b56a171 (diff)
DO NOT MERGE Video call upgrade/dowgrade request changes.
- fixed potential NPE in VideoCallFragment when setting preview size. - moved photo load into the postExecute for the async task -- it is already threaded and I was seeing intermittent concurrency issues. - Changed CallButtonFragment to retrieve max # of buttons from config.xml. - Added override for wider screens (e.g. N6 and wider) to show an extra button. - Reorganized call buttons so that the "Camera on/off" button is adjacent to the flip camera button. - Changed answer Glowpad to pass correct video state so that accepting a video request uses the correct state (important for accepting requests to turn camera back on). - added new Session modification state REQUEST_REJECTED for when the remote user explicitly declines the request. This is used to trigger a "video request rejected" message when the remote party rejects the request. Bug: 20257400 Change-Id: Ibe25eb045ee868748f91bf411f285629d36ebcd2 (cherry picked from commit 1a723f1586c812510bd0791a4ef8420d36f83cf9)
-rw-r--r--InCallUI/res/layout/call_button_fragment.xml14
-rw-r--r--InCallUI/res/layout/call_card_fragment.xml7
-rw-r--r--InCallUI/res/values-sw410dp/config.xml21
-rw-r--r--InCallUI/res/values/array.xml51
-rw-r--r--InCallUI/res/values/config.xml20
-rw-r--r--InCallUI/res/values/strings.xml4
-rw-r--r--InCallUI/src/com/android/incallui/AnswerFragment.java56
-rw-r--r--InCallUI/src/com/android/incallui/AnswerPresenter.java41
-rw-r--r--InCallUI/src/com/android/incallui/Call.java3
-rw-r--r--InCallUI/src/com/android/incallui/CallButtonFragment.java12
-rw-r--r--InCallUI/src/com/android/incallui/CallButtonPresenter.java1
-rw-r--r--InCallUI/src/com/android/incallui/CallCardFragment.java133
-rw-r--r--InCallUI/src/com/android/incallui/CallCardPresenter.java64
-rw-r--r--InCallUI/src/com/android/incallui/CallList.java24
-rw-r--r--InCallUI/src/com/android/incallui/GlowPadWrapper.java17
-rw-r--r--InCallUI/src/com/android/incallui/InCallVideoCallCallback.java15
-rw-r--r--InCallUI/src/com/android/incallui/StatusBarNotifier.java35
-rw-r--r--InCallUI/src/com/android/incallui/VideoCallFragment.java10
-rw-r--r--InCallUI/src/com/android/incallui/VideoCallPresenter.java45
19 files changed, 378 insertions, 195 deletions
diff --git a/InCallUI/res/layout/call_button_fragment.xml b/InCallUI/res/layout/call_button_fragment.xml
index 17c2d7c78..0cdaf23f7 100644
--- a/InCallUI/res/layout/call_button_fragment.xml
+++ b/InCallUI/res/layout/call_button_fragment.xml
@@ -122,6 +122,13 @@
<!-- This slot is either "Add" or "Merge", depending on the state of the call. One or the
other of these must always be set to GONE. -->
+ <!-- "Turn off camera" for video calls. -->
+ <ToggleButton android:id="@+id/pauseVideoButton"
+ style="@style/InCallCompoundButton"
+ android:background="@drawable/btn_compound_video_off"
+ android:contentDescription="@string/onscreenPauseVideoText"
+ android:visibility="gone" />
+
<!-- "Add Call" -->
<ImageButton android:id="@+id/addButton"
style="@style/InCallButton"
@@ -138,13 +145,6 @@
android:contentDescription="@string/onscreenMergeCallsText"
android:visibility="gone" />
- <!-- "Turn off camera" for video calls. -->
- <ToggleButton android:id="@+id/pauseVideoButton"
- style="@style/InCallCompoundButton"
- android:background="@drawable/btn_compound_video_off"
- android:contentDescription="@string/onscreenPauseVideoText"
- android:visibility="gone" />
-
<!-- "Overflow" -->
<ImageButton android:id="@+id/overflowButton"
style="@style/InCallButton"
diff --git a/InCallUI/res/layout/call_card_fragment.xml b/InCallUI/res/layout/call_card_fragment.xml
index 1971c9c70..a21ed20d8 100644
--- a/InCallUI/res/layout/call_card_fragment.xml
+++ b/InCallUI/res/layout/call_card_fragment.xml
@@ -80,6 +80,13 @@
</FrameLayout>
+ <fragment android:name="com.android.incallui.VideoCallFragment"
+ android:id="@+id/videoCallFragment"
+ android:layout_alignParentTop="true"
+ android:layout_gravity="top|center_horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
<!-- Progress spinner, useful for indicating pending operations such as upgrade to video. -->
<FrameLayout
android:id="@+id/progressSpinner"
diff --git a/InCallUI/res/values-sw410dp/config.xml b/InCallUI/res/values-sw410dp/config.xml
new file mode 100644
index 000000000..a57f86784
--- /dev/null
+++ b/InCallUI/res/values-sw410dp/config.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ 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.
+ ~ 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
+ -->
+
+<resources>
+ <!-- Determines the maximum number of buttons visible on the call card. Any buttons over this
+ count are put into the overflow menu. -->
+ <integer name="call_card_max_buttons">6</integer>
+</resources> \ No newline at end of file
diff --git a/InCallUI/res/values/array.xml b/InCallUI/res/values/array.xml
index 2e38c2c46..7877ec8f3 100644
--- a/InCallUI/res/values/array.xml
+++ b/InCallUI/res/values/array.xml
@@ -112,61 +112,24 @@
<item>@string/description_direction_down</item>
</array>
-
- <!-- For upgrade to video from VOLTE to VT (Tx/Rx/Bidirectional) in an active video call.
+ <!-- For accept/reject upgrade to video in active video call
- Accept upgrade to video request (drag right)
- - Decline upgrade to video request (drag left)
- - Answer as audio call (drag down) -->
- <array name="incoming_call_widget_video_upgrade_request_targets">
+ - Decline upgrade to video request (drag left)-->
+ <array name="incoming_call_widget_video_request_targets">
<item>@drawable/ic_lockscreen_answer_video</item>
- <item>@null</item>
- <item>@drawable/ic_lockscreen_decline</item>
- <item>@drawable/ic_lockscreen_answer</item>
+ <item>@drawable/ic_lockscreen_decline_video</item>
</array>
- <array name="incoming_call_widget_video_upgrade_request_target_descriptions">
+
+ <array name="incoming_call_widget_video_request_target_descriptions">
<item>@string/description_target_accept_upgrade_to_video_request</item>
<item>@null</item>
<item>@string/description_target_decline_upgrade_to_video_request</item>
<item>@null</item>"
</array>
- <array name="incoming_call_widget_video_upgrade_request_target_direction_descriptions">
+ <array name="incoming_call_widget_video_request_target_direction_descriptions">
<item>@string/description_direction_right</item>
<item>@null</item>
<item>@string/description_direction_left</item>
<item>@null</item>
</array>
-
- <!-- For accept/reject upgrade to video in active video call
- - Accept upgrade to video request (drag right)
- - Decline upgrade to video request (drag left)-->
- <array name="incoming_call_widget_bidirectional_video_accept_reject_request_targets">
- <item>@drawable/ic_lockscreen_answer_video</item>
- <item>@drawable/ic_lockscreen_decline</item>
- </array>
-
- <!-- 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)
- 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_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_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_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_request</item>
- <item>@string/description_target_decline_upgrade_to_video_request</item>
- </array>
-
</resources>
diff --git a/InCallUI/res/values/config.xml b/InCallUI/res/values/config.xml
new file mode 100644
index 000000000..8acbd5910
--- /dev/null
+++ b/InCallUI/res/values/config.xml
@@ -0,0 +1,20 @@
+<!--
+ ~ 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.
+ ~ 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
+ -->
+<resources>
+ <!-- Determines the maximum number of buttons visible on the call card. Any buttons over this
+ count are put into the overflow menu. -->
+ <integer name="call_card_max_buttons">5</integer>
+</resources> \ No newline at end of file
diff --git a/InCallUI/res/values/strings.xml b/InCallUI/res/values/strings.xml
index f913f68a4..c985a8cc7 100644
--- a/InCallUI/res/values/strings.xml
+++ b/InCallUI/res/values/strings.xml
@@ -114,8 +114,8 @@
<string name="card_title_video_call_requesting">Requesting video</string>
<!-- In-call screen: status label when there is a problem connecting a video call. -->
<string name="card_title_video_call_error">Can\'t connect video call</string>
- <!-- In-call screen: status label when in a paused video call. -->
- <string name="card_title_video_call_paused">Video call (Paused)</string>
+ <!-- In-call screen: status label when the remote party rejects a video call request. -->
+ <string name="card_title_video_call_rejected">Video request rejected</string>
<!-- In-call screen: string shown to the user when their outgoing number is different than the
number reported by TelephonyManager#getLine1Number() -->
diff --git a/InCallUI/src/com/android/incallui/AnswerFragment.java b/InCallUI/src/com/android/incallui/AnswerFragment.java
index 07cbfd573..d68a316c9 100644
--- a/InCallUI/src/com/android/incallui/AnswerFragment.java
+++ b/InCallUI/src/com/android/incallui/AnswerFragment.java
@@ -21,6 +21,7 @@ import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
+import android.telecom.VideoProfile;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
@@ -49,10 +50,7 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente
public static final int TARGET_SET_FOR_AUDIO_WITH_SMS = 1;
public static final int TARGET_SET_FOR_VIDEO_WITHOUT_SMS = 2;
public static final int TARGET_SET_FOR_VIDEO_WITH_SMS = 3;
- public static final int TARGET_SET_FOR_VIDEO_UPGRADE_REQUEST = 4;
- public static final int TARGET_SET_FOR_BIDIRECTIONAL_VIDEO_ACCEPT_REJECT_REQUEST = 5;
- public static final int TARGET_SET_FOR_VIDEO_TRANSMIT_ACCEPT_REJECT_REQUEST = 6;
- public static final int TARGET_SET_FOR_VIDEO_RECEIVE_ACCEPT_REJECT_REQUEST = 7;
+ public static final int TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST = 4;
/**
* The popup showing the list of canned responses.
@@ -124,12 +122,21 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente
* Sets targets on the glowpad according to target set identified by the parameter.
* @param targetSet Integer identifying the set of targets to use.
*/
- @Override
public void showTargets(int targetSet) {
+ showTargets(targetSet, VideoProfile.VideoState.BIDIRECTIONAL);
+ }
+
+ /**
+ * Sets targets on the glowpad according to target set identified by the parameter.
+ * @param targetSet Integer identifying the set of targets to use.
+ */
+ @Override
+ public void showTargets(int targetSet, int videoState) {
final int targetResourceId;
final int targetDescriptionsResourceId;
final int directionDescriptionsResourceId;
final int handleDrawableResourceId;
+ mGlowpad.setVideoState(videoState);
switch (targetSet) {
case TARGET_SET_FOR_AUDIO_WITH_SMS:
@@ -156,39 +163,13 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente
R.array.incoming_call_widget_video_with_sms_direction_descriptions;
handleDrawableResourceId = R.drawable.ic_incall_video_handle;
break;
- case TARGET_SET_FOR_VIDEO_UPGRADE_REQUEST:
- targetResourceId = R.array.incoming_call_widget_video_upgrade_request_targets;
- targetDescriptionsResourceId =
- R.array.incoming_call_widget_video_upgrade_request_target_descriptions;
- directionDescriptionsResourceId = R.array
- .incoming_call_widget_video_upgrade_request_target_direction_descriptions;
- handleDrawableResourceId = R.drawable.ic_incall_video_handle;
- break;
- case TARGET_SET_FOR_BIDIRECTIONAL_VIDEO_ACCEPT_REJECT_REQUEST:
+ case TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST:
targetResourceId =
- R.array.incoming_call_widget_bidirectional_video_accept_reject_request_targets;
+ R.array.incoming_call_widget_video_request_targets;
targetDescriptionsResourceId =
- R.array.incoming_call_widget_video_upgrade_request_target_descriptions;
+ R.array.incoming_call_widget_video_request_target_descriptions;
directionDescriptionsResourceId = R.array
- .incoming_call_widget_video_upgrade_request_target_direction_descriptions;
- handleDrawableResourceId = R.drawable.ic_incall_video_handle;
- break;
- case TARGET_SET_FOR_VIDEO_TRANSMIT_ACCEPT_REJECT_REQUEST:
- targetResourceId =
- R.array.incoming_call_widget_video_transmit_accept_reject_request_targets;
- targetDescriptionsResourceId =
- R.array.incoming_call_widget_video_transmit_request_target_descriptions;
- directionDescriptionsResourceId = R.array
- .incoming_call_widget_video_upgrade_request_target_direction_descriptions;
- handleDrawableResourceId = R.drawable.ic_incall_video_handle;
- break;
- case TARGET_SET_FOR_VIDEO_RECEIVE_ACCEPT_REJECT_REQUEST:
- targetResourceId =
- R.array.incoming_call_widget_video_receive_accept_reject_request_targets;
- targetDescriptionsResourceId =
- R.array.incoming_call_widget_video_receive_request_target_descriptions;
- directionDescriptionsResourceId = R.array
- .incoming_call_widget_video_upgrade_request_target_direction_descriptions;
+ .incoming_call_widget_video_request_target_direction_descriptions;
handleDrawableResourceId = R.drawable.ic_incall_video_handle;
break;
case TARGET_SET_FOR_AUDIO_WITHOUT_SMS:
@@ -376,6 +357,11 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente
}
@Override
+ public void onDeclineUpgradeRequest(Context context) {
+ InCallPresenter.getInstance().declineUpgradeRequest(context);
+ }
+
+ @Override
public void onText() {
getPresenter().onText();
}
diff --git a/InCallUI/src/com/android/incallui/AnswerPresenter.java b/InCallUI/src/com/android/incallui/AnswerPresenter.java
index dc2d9c551..6628f2f86 100644
--- a/InCallUI/src/com/android/incallui/AnswerPresenter.java
+++ b/InCallUI/src/com/android/incallui/AnswerPresenter.java
@@ -97,6 +97,17 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi>
public void onDisconnect(Call call) {
// no-op
}
+
+ public void onSessionModificationStateChange(int sessionModificationState) {
+ boolean isUpgradePending = sessionModificationState ==
+ Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST;
+
+ if (!isUpgradePending) {
+ // Stop listening for updates.
+ CallList.getInstance().removeCallUpdateListener(mCallId, this);
+ showAnswerUi(false);
+ }
+ }
private boolean isVideoUpgradePending(Call call) {
return call.getSessionModificationState()
@@ -166,27 +177,15 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi>
return;
}
- showAnswerUi(true);
- getUi().showTargets(getUiTarget(currentVideoState, modifyToVideoState));
-
- }
+ AnswerUi ui = getUi();
- private int getUiTarget(int currentVideoState, int modifyToVideoState) {
- if (showVideoUpgradeOptions(currentVideoState, modifyToVideoState)) {
- return AnswerFragment.TARGET_SET_FOR_VIDEO_UPGRADE_REQUEST;
- } else if (isEnabled(modifyToVideoState, VideoProfile.VideoState.BIDIRECTIONAL)) {
- return AnswerFragment.TARGET_SET_FOR_BIDIRECTIONAL_VIDEO_ACCEPT_REJECT_REQUEST;
- } else if (isEnabled(modifyToVideoState, VideoProfile.VideoState.TX_ENABLED)) {
- return AnswerFragment.TARGET_SET_FOR_VIDEO_TRANSMIT_ACCEPT_REJECT_REQUEST;
- } else if (isEnabled(modifyToVideoState, VideoProfile.VideoState.RX_ENABLED)) {
- return AnswerFragment.TARGET_SET_FOR_VIDEO_RECEIVE_ACCEPT_REJECT_REQUEST;
+ if (ui == null) {
+ Log.e(this, "Ui is null. Can't process upgrade request");
+ return;
}
- return AnswerFragment.TARGET_SET_FOR_VIDEO_UPGRADE_REQUEST;
- }
-
- private boolean showVideoUpgradeOptions(int currentVideoState, int modifyToVideoState) {
- return currentVideoState == VideoProfile.VideoState.AUDIO_ONLY &&
- isEnabled(modifyToVideoState, VideoProfile.VideoState.BIDIRECTIONAL);
+ showAnswerUi(true);
+ ui.showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST,
+ modifyToVideoState);
}
private boolean isEnabled(int videoState, int mask) {
@@ -220,15 +219,16 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi>
}
public void onAnswer(int videoState, Context context) {
- Log.d(this, "onAnswer mCallId=" + mCallId + " videoState=" + videoState);
if (mCallId == null) {
return;
}
if (mCall.getSessionModificationState()
== Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
+ Log.d(this, "onAnswer (upgradeCall) mCallId=" + mCallId + " videoState=" + videoState);
InCallPresenter.getInstance().acceptUpgradeRequest(videoState, context);
} else {
+ Log.d(this, "onAnswer (answerCall) mCallId=" + mCallId + " videoState=" + videoState);
TelecomAdapter.getInstance().answerCall(mCall.getId(), videoState);
}
}
@@ -293,6 +293,7 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi>
interface AnswerUi extends Ui {
public void onShowAnswerUi(boolean shown);
public void showTargets(int targetSet);
+ public void showTargets(int targetSet, int videoState);
public void showMessageDialog();
public void configureMessageDialog(List<String> textResponses);
public Context getContext();
diff --git a/InCallUI/src/com/android/incallui/Call.java b/InCallUI/src/com/android/incallui/Call.java
index 18eb7471e..9f58fbed5 100644
--- a/InCallUI/src/com/android/incallui/Call.java
+++ b/InCallUI/src/com/android/incallui/Call.java
@@ -124,6 +124,7 @@ public class Call {
public static final int REQUEST_FAILED = 2;
public static final int RECEIVED_UPGRADE_TO_VIDEO_REQUEST = 3;
public static final int UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT = 4;
+ public static final int REQUEST_REJECTED = 5;
}
public static class VideoSettings {
@@ -510,7 +511,7 @@ public class Call {
Log.d(this, "setSessionModificationState " + state + " mSessionModificationState="
+ mSessionModificationState);
if (hasChanged) {
- update();
+ CallList.getInstance().onSessionModificationStateChange(this, state);
}
}
diff --git a/InCallUI/src/com/android/incallui/CallButtonFragment.java b/InCallUI/src/com/android/incallui/CallButtonFragment.java
index 506ca7dcc..9def35694 100644
--- a/InCallUI/src/com/android/incallui/CallButtonFragment.java
+++ b/InCallUI/src/com/android/incallui/CallButtonFragment.java
@@ -18,9 +18,7 @@ package com.android.incallui;
import static com.android.incallui.CallButtonFragment.Buttons.*;
-import android.app.AlertDialog;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
@@ -30,8 +28,6 @@ import android.graphics.drawable.RippleDrawable;
import android.graphics.drawable.StateListDrawable;
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;
@@ -43,12 +39,10 @@ import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.PopupMenu;
-import android.widget.Toast;
import android.widget.PopupMenu.OnDismissListener;
import android.widget.PopupMenu.OnMenuItemClickListener;
import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
-import java.util.ArrayList;
/**
* Fragment for call control buttons
@@ -58,7 +52,7 @@ public class CallButtonFragment
implements CallButtonPresenter.CallButtonUi, OnMenuItemClickListener, OnDismissListener,
View.OnClickListener {
private static final int INVALID_INDEX = -1;
- private static final int BUTTON_MAX_VISIBLE = 5;
+ private int mButtonMaxVisible;
// The button is currently visible in the UI
private static final int BUTTON_VISIBLE = 1;
// The button is hidden in the UI
@@ -127,6 +121,8 @@ public class CallButtonFragment
for (int i = 0; i < BUTTON_COUNT; i++) {
mButtonVisibilityMap.put(i, BUTTON_HIDDEN);
}
+
+ mButtonMaxVisible = getResources().getInteger(R.integer.call_card_max_buttons);
}
@Override
@@ -458,7 +454,7 @@ public class CallButtonFragment
final View button = getButtonById(i);
if (visibility == BUTTON_VISIBLE) {
visibleCount++;
- if (visibleCount <= BUTTON_MAX_VISIBLE) {
+ if (visibleCount <= mButtonMaxVisible) {
button.setVisibility(View.VISIBLE);
prevVisibleButton = button;
prevVisibleId = i;
diff --git a/InCallUI/src/com/android/incallui/CallButtonPresenter.java b/InCallUI/src/com/android/incallui/CallButtonPresenter.java
index 43ee3326b..d788a1097 100644
--- a/InCallUI/src/com/android/incallui/CallButtonPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallButtonPresenter.java
@@ -322,6 +322,7 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
VideoProfile videoProfile = new VideoProfile(
mCall.getVideoState() | VideoProfile.VideoState.TX_ENABLED);
videoCall.sendSessionModifyRequest(videoProfile);
+ mCall.setSessionModificationState(Call.SessionModificationState.WAITING_FOR_RESPONSE);
}
getUi().setVideoPaused(pause);
}
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index 691589ca0..2acabd694 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -31,6 +31,8 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.Trace;
+import android.os.Handler;
+import android.os.Looper;
import android.telecom.DisconnectCause;
import android.telecom.VideoProfile;
import android.telephony.PhoneNumberUtils;
@@ -63,6 +65,38 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
implements CallCardPresenter.CallCardUi {
private static final String TAG = "CallCardFragment";
+ /**
+ * Internal class which represents the call state label which is to be applied.
+ */
+ private class CallStateLabel {
+ private CharSequence mCallStateLabel;
+ private boolean mIsAutoDismissing;
+
+ public CallStateLabel(CharSequence callStateLabel, boolean isAutoDismissing) {
+ mCallStateLabel = callStateLabel;
+ mIsAutoDismissing = isAutoDismissing;
+ }
+
+ public CharSequence getCallStateLabel() {
+ return mCallStateLabel;
+ }
+
+ /**
+ * Determines if the call state label should auto-dismiss.
+ *
+ * @return {@code true} if the call state label should auto-dismiss.
+ */
+ public boolean isAutoDismissing() {
+ return mIsAutoDismissing;
+ }
+ };
+
+ /**
+ * The duration of time (in milliseconds) a call state label should remain visible before
+ * resetting to its previous value.
+ */
+ private static final long CALL_STATE_LABEL_RESET_DELAY_MS = 3000;
+
private AnimatorSet mAnimatorSet;
private int mShrinkAnimationDuration;
private int mFabNormalDiameter;
@@ -119,6 +153,13 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
private MaterialPalette mCurrentThemeColors;
+ /**
+ * Call state label to set when an auto-dismissing call state label is dismissed.
+ */
+ private CharSequence mPostResetCallStateLabel;
+ private boolean mCallStateLabelResetPending = false;
+ private Handler mHandler;
+
@Override
public CallCardPresenter.CallCardUi getUi() {
return this;
@@ -133,6 +174,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mHandler = new Handler(Looper.getMainLooper());
mShrinkAnimationDuration = getResources().getInteger(R.integer.shrink_animation_duration);
mVideoAnimationDuration = getResources().getInteger(R.integer.video_animation_duration);
mFloatingActionButtonVerticalOffset = getResources().getDimensionPixelOffset(
@@ -492,15 +534,16 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
boolean isWifi,
boolean isConference) {
boolean isGatewayCall = !TextUtils.isEmpty(gatewayNumber);
- CharSequence callStateLabel = getCallStateLabelFromState(state, videoState,
+ CallStateLabel callStateLabel = getCallStateLabelFromState(state, videoState,
sessionModificationState, disconnectCause, connectionLabel, isGatewayCall, isWifi,
isConference);
- Log.v(this, "setCallState " + callStateLabel);
+ Log.v(this, "setCallState " + callStateLabel.getCallStateLabel());
+ Log.v(this, "AutoDismiss " + callStateLabel.isAutoDismissing());
Log.v(this, "DisconnectCause " + disconnectCause.toString());
Log.v(this, "gateway " + connectionLabel + gatewayNumber);
- if (TextUtils.equals(callStateLabel, mCallStateLabel.getText())) {
+ if (TextUtils.equals(callStateLabel.getCallStateLabel(), mCallStateLabel.getText())) {
// Nothing to do if the labels are the same
if (state == Call.State.ACTIVE || state == Call.State.CONFERENCED) {
mCallStateLabel.clearAnimation();
@@ -510,24 +553,13 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
}
// Update the call state label and icon.
- if (!TextUtils.isEmpty(callStateLabel)) {
- mCallStateLabel.setText(callStateLabel);
- mCallStateLabel.setAlpha(1);
- mCallStateLabel.setVisibility(View.VISIBLE);
-
+ setCallStateLabel(callStateLabel);
+ if (!TextUtils.isEmpty(callStateLabel.getCallStateLabel())) {
if (state == Call.State.ACTIVE || state == Call.State.CONFERENCED) {
mCallStateLabel.clearAnimation();
} else {
mCallStateLabel.startAnimation(mPulseAnimation);
}
- } else {
- Animation callStateLabelAnimation = mCallStateLabel.getAnimation();
- if (callStateLabelAnimation != null) {
- callStateLabelAnimation.cancel();
- }
- mCallStateLabel.setText(null);
- mCallStateLabel.setAlpha(0);
- mCallStateLabel.setVisibility(View.GONE);
}
if (callStateIcon != null) {
@@ -538,7 +570,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
mCallStateIcon.setImageDrawable(callStateIcon);
if (state == Call.State.ACTIVE || state == Call.State.CONFERENCED
- || TextUtils.isEmpty(callStateLabel)) {
+ || TextUtils.isEmpty(callStateLabel.getCallStateLabel())) {
mCallStateIcon.clearAnimation();
} else {
mCallStateIcon.startAnimation(mPulseAnimation);
@@ -569,7 +601,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
if (state == Call.State.INCOMING) {
if (callStateLabel != null) {
- getView().announceForAccessibility(callStateLabel);
+ getView().announceForAccessibility(callStateLabel.getCallStateLabel());
}
if (mPrimaryName.getText() != null) {
getView().announceForAccessibility(mPrimaryName.getText());
@@ -577,6 +609,50 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
}
}
+ private void setCallStateLabel(CallStateLabel callStateLabel) {
+ Log.v(this, "setCallStateLabel : label = " + callStateLabel.getCallStateLabel());
+
+ if (callStateLabel.isAutoDismissing()) {
+ mCallStateLabelResetPending = true;
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ Log.v(this, "restoringCallStateLabel : label = " +
+ mPostResetCallStateLabel);
+ changeCallStateLabel(mPostResetCallStateLabel);
+ mCallStateLabelResetPending = false;
+ }
+ }, CALL_STATE_LABEL_RESET_DELAY_MS);
+
+ changeCallStateLabel(callStateLabel.getCallStateLabel());
+ } else {
+ // Keep track of the current call state label; used when resetting auto dismissing
+ // call state labels.
+ mPostResetCallStateLabel = callStateLabel.getCallStateLabel();
+
+ if (!mCallStateLabelResetPending) {
+ changeCallStateLabel(callStateLabel.getCallStateLabel());
+ }
+ }
+ }
+
+ private void changeCallStateLabel(CharSequence callStateLabel) {
+ Log.v(this, "changeCallStateLabel : label = " + callStateLabel);
+ if (!TextUtils.isEmpty(callStateLabel)) {
+ mCallStateLabel.setText(callStateLabel);
+ mCallStateLabel.setAlpha(1);
+ mCallStateLabel.setVisibility(View.VISIBLE);
+ } else {
+ Animation callStateLabelAnimation = mCallStateLabel.getAnimation();
+ if (callStateLabelAnimation != null) {
+ callStateLabelAnimation.cancel();
+ }
+ mCallStateLabel.setText(null);
+ mCallStateLabel.setAlpha(0);
+ mCallStateLabel.setVisibility(View.GONE);
+ }
+ }
+
@Override
public void setCallbackNumber(String callbackNumber, boolean isEmergencyCall) {
if (mInCallMessageLabel == null) {
@@ -670,7 +746,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
*
* TODO: Move this to the CallCardPresenter.
*/
- private CharSequence getCallStateLabelFromState(int state, int videoState,
+ private CallStateLabel getCallStateLabelFromState(int state, int videoState,
int sessionModificationState, DisconnectCause disconnectCause, String label,
boolean isGatewayCall, boolean isWifi, boolean isConference) {
final Context context = getView().getContext();
@@ -678,6 +754,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
boolean hasSuggestedLabel = label != null;
boolean isAccount = hasSuggestedLabel && !isGatewayCall;
+ boolean isAutoDismissing = false;
switch (state) {
case Call.State.IDLE:
@@ -689,15 +766,20 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
if ((isAccount || isWifi || isConference) && hasSuggestedLabel) {
callStateLabel = label;
} else if (sessionModificationState
+ == Call.SessionModificationState.REQUEST_REJECTED) {
+ callStateLabel = context.getString(R.string.card_title_video_call_rejected);
+ isAutoDismissing = true;
+ } else if (sessionModificationState
== Call.SessionModificationState.REQUEST_FAILED) {
callStateLabel = context.getString(R.string.card_title_video_call_error);
+ isAutoDismissing = true;
} else if (sessionModificationState
== Call.SessionModificationState.WAITING_FOR_RESPONSE) {
callStateLabel = context.getString(R.string.card_title_video_call_requesting);
- } else if (CallUtils.isVideoCall(videoState) &&
- VideoProfile.VideoState.isPaused(videoState)) {
- callStateLabel = context.getString(R.string.card_title_video_call_paused);
- } else if (VideoProfile.VideoState.isBidirectional(videoState)) {
+ } else if (sessionModificationState
+ == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
+ callStateLabel = context.getString(R.string.card_title_video_call_requesting);
+ } else if (CallUtils.isVideoCall(videoState)) {
callStateLabel = context.getString(R.string.card_title_video_call);
}
break;
@@ -721,7 +803,8 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
callStateLabel = label;
} else if (isAccount) {
callStateLabel = context.getString(R.string.incoming_via_template, label);
- } else if (VideoProfile.VideoState.isBidirectional(videoState)) {
+ } else if (VideoProfile.VideoState.isTransmissionEnabled(videoState) ||
+ VideoProfile.VideoState.isReceptionEnabled(videoState)) {
callStateLabel = context.getString(R.string.notification_incoming_video_call);
} else {
callStateLabel = context.getString(R.string.card_title_incoming_call);
@@ -748,7 +831,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
default:
Log.wtf(this, "updateCallStateWidgets: unexpected call: " + state);
}
- return callStateLabel;
+ return new CallStateLabel(callStateLabel, isAutoDismissing);
}
private void showAndInitializeSecondaryCallInfo(boolean hasProvider) {
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index ee13e061f..b233ad56b 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -48,6 +48,7 @@ import com.android.incallui.InCallPresenter.IncomingCallListener;
import com.android.incalluibind.ObjectFactory;
import java.lang.ref.WeakReference;
+import java.util.Objects;
import com.google.common.base.Preconditions;
@@ -58,7 +59,7 @@ import com.google.common.base.Preconditions;
*/
public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
implements InCallStateListener, IncomingCallListener, InCallDetailsListener,
- InCallEventListener {
+ InCallEventListener, CallList.CallUpdateListener {
public interface EmergencyCallListener {
public void onCallUpdated(BaseFragment fragment, boolean isEmergency);
@@ -75,8 +76,8 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
private ContactCacheEntry mPrimaryContactInfo;
private ContactCacheEntry mSecondaryContactInfo;
private CallTimer mCallTimer;
-
private Context mContext;
+ private boolean mSpinnerShowing = false;
public static class ContactLookupCallback implements ContactInfoCacheCallback {
private final WeakReference<CallCardPresenter> mCallCardPresenter;
@@ -121,6 +122,7 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
// Call may be null if disconnect happened already.
if (call != null) {
mPrimary = call;
+ CallList.getInstance().addCallUpdateListener(call.getId(), this);
// start processing lookups right away.
if (!call.isConferenceCall()) {
@@ -158,6 +160,9 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
InCallPresenter.getInstance().removeIncomingCallListener(this);
InCallPresenter.getInstance().removeDetailsListener(this);
InCallPresenter.getInstance().removeInCallEventListener(this);
+ if (mPrimary != null) {
+ CallList.getInstance().removeCallUpdateListener(mPrimary.getId(), this);
+ }
mPrimary = null;
mPrimaryContactInfo = null;
@@ -204,6 +209,7 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
final boolean secondaryChanged = !Call.areSame(mSecondary, secondary);
mSecondary = secondary;
+ Call previousPrimary = mPrimary;
mPrimary = primary;
// Refresh primary call information if either:
@@ -212,6 +218,11 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
if (mPrimary != null && (primaryChanged ||
ui.isManageConferenceVisible() != shouldShowManageConference())) {
// primary call has changed
+ if (previousPrimary != null) {
+ CallList.getInstance().removeCallUpdateListener(previousPrimary.getId(), this);
+ }
+ CallList.getInstance().addCallUpdateListener(mPrimary.getId(), this);
+
mPrimaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mPrimary,
mPrimary.getState() == Call.State.INCOMING);
updatePrimaryDisplayInfo();
@@ -262,7 +273,6 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
}
maybeShowManageConferenceCallButton();
- maybeShowProgressSpinner();
// Hide the end call button instantly if we're receiving an incoming call.
getUi().setEndCallButtonEnabled(shouldShowEndCallButton(mPrimary, callState),
@@ -279,6 +289,32 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
}
}
+ @Override
+ public void onCallChanged(Call call) {
+ // No-op; specific call updates handled elsewhere.
+ }
+
+ /**
+ * Handles a change to the session modification state for a call. Triggers showing the progress
+ * spinner, as well as updating the call state label.
+ *
+ * @param sessionModificationState The new session modification state.
+ */
+ @Override
+ public void onSessionModificationStateChange(int sessionModificationState) {
+ Log.d(this, "onSessionModificationStateChange : sessionModificationState = " +
+ sessionModificationState);
+
+ if (mPrimary == null) {
+ return;
+ }
+ maybeShowProgressSpinner(mPrimary.getState(), sessionModificationState);
+ getUi().setEndCallButtonEnabled(sessionModificationState !=
+ Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST,
+ true /* shouldAnimate */);
+ updatePrimaryCallState();
+ }
+
private String getSubscriptionNumber() {
// If it's an emergency call, and they're not populating the callback number,
// then try to fall back to the phone sub info (to hopefully get the SIM's
@@ -322,11 +358,21 @@ 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 a pending session modification exists for the current call. If so, the
+ * progress spinner is shown, and the call state is updated.
+ *
+ * @param callState The call state.
+ * @param sessionModificationState The session modification state.
+ */
+ private void maybeShowProgressSpinner(int callState, int sessionModificationState) {
+ final boolean show = sessionModificationState ==
+ Call.SessionModificationState.WAITING_FOR_RESPONSE
+ && callState == Call.State.ACTIVE;
+ if (show != mSpinnerShowing) {
+ getUi().setProgressSpinnerVisible(show);
+ mSpinnerShowing = show;
+ }
}
/**
@@ -657,7 +703,7 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
}
private boolean hasOutgoingGatewayCall() {
- // We only display the gateway information while STATE_DIALING so return false for any othe
+ // We only display the gateway information while STATE_DIALING so return false for any other
// call state.
// TODO: mPrimary can be null because this is called from updatePrimaryDisplayInfo which
// is also called after a contact search completes (call is not present yet). Split the
diff --git a/InCallUI/src/com/android/incallui/CallList.java b/InCallUI/src/com/android/incallui/CallList.java
index d89fead9a..e937bb162 100644
--- a/InCallUI/src/com/android/incallui/CallList.java
+++ b/InCallUI/src/com/android/incallui/CallList.java
@@ -142,6 +142,21 @@ public class CallList {
Trace.endSection();
}
+ /**
+ * Called when a single call has changed session modification state.
+ *
+ * @param call The call.
+ * @param sessionModificationState The new session modification state.
+ */
+ public void onSessionModificationStateChange(Call call, int sessionModificationState) {
+ final List<CallUpdateListener> listeners = mCallUpdateListenerMap.get(call.getId());
+ if (listeners != null) {
+ for (CallUpdateListener listener : listeners) {
+ listener.onSessionModificationStateChange(sessionModificationState);
+ }
+ }
+ }
+
public void notifyCallUpdateListeners(Call call) {
final List<CallUpdateListener> listeners = mCallUpdateListenerMap.get(call.getId());
if (listeners != null) {
@@ -556,10 +571,19 @@ public class CallList {
* that will get called upon disconnection.
*/
public void onDisconnect(Call call);
+
+
}
public interface CallUpdateListener {
// TODO: refactor and limit arg to be call state. Caller info is not needed.
public void onCallChanged(Call call);
+
+ /**
+ * Notifies of a change to the session modification state for a call.
+ *
+ * @param sessionModificationState The new session modification state.
+ */
+ public void onSessionModificationStateChange(int sessionModificationState);
}
}
diff --git a/InCallUI/src/com/android/incallui/GlowPadWrapper.java b/InCallUI/src/com/android/incallui/GlowPadWrapper.java
index 58a5f30ea..177669668 100644
--- a/InCallUI/src/com/android/incallui/GlowPadWrapper.java
+++ b/InCallUI/src/com/android/incallui/GlowPadWrapper.java
@@ -49,6 +49,7 @@ public class GlowPadWrapper extends GlowPadView implements GlowPadView.OnTrigger
private AnswerListener mAnswerListener;
private boolean mPingEnabled = true;
private boolean mTargetTriggered = false;
+ private int mVideoState = VideoProfile.VideoState.BIDIRECTIONAL;
public GlowPadWrapper(Context context) {
super(context);
@@ -125,11 +126,11 @@ public class GlowPadWrapper extends GlowPadView implements GlowPadView.OnTrigger
break;
case R.drawable.ic_videocam:
case R.drawable.ic_lockscreen_answer_video:
- mAnswerListener.onAnswer(VideoProfile.VideoState.BIDIRECTIONAL, getContext());
+ mAnswerListener.onAnswer(mVideoState, getContext());
mTargetTriggered = true;
break;
- case R.drawable.ic_toolbar_video_off:
- InCallPresenter.getInstance().declineUpgradeRequest(getContext());
+ case R.drawable.ic_lockscreen_decline_video:
+ mAnswerListener.onDeclineUpgradeRequest(getContext());
mTargetTriggered = true;
break;
default:
@@ -152,9 +153,19 @@ public class GlowPadWrapper extends GlowPadView implements GlowPadView.OnTrigger
mAnswerListener = listener;
}
+ /**
+ * Sets the video state represented by the "video" icon on the glow pad.
+ *
+ * @param videoState The new video state.
+ */
+ public void setVideoState(int videoState) {
+ mVideoState = videoState;
+ }
+
public interface AnswerListener {
void onAnswer(int videoState, Context context);
void onDecline(Context context);
+ void onDeclineUpgradeRequest(Context context);
void onText();
}
}
diff --git a/InCallUI/src/com/android/incallui/InCallVideoCallCallback.java b/InCallUI/src/com/android/incallui/InCallVideoCallCallback.java
index ba4ab660d..ede1129cd 100644
--- a/InCallUI/src/com/android/incallui/InCallVideoCallCallback.java
+++ b/InCallUI/src/com/android/incallui/InCallVideoCallCallback.java
@@ -80,6 +80,19 @@ public class InCallVideoCallCallback extends VideoCall.Callback {
Log.d(this, "onSessionModifyResponseReceived status=" + status + " requestedProfile="
+ requestedProfile + " responseProfile=" + responseProfile);
if (status != VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS) {
+ // Report the reason the upgrade failed as the new session modification state.
+ if (status == VideoProvider.SESSION_MODIFY_REQUEST_TIMED_OUT) {
+ mCall.setSessionModificationState(
+ Call.SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT);
+ } else {
+ if (status == VideoProvider.SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE) {
+ mCall.setSessionModificationState(
+ Call.SessionModificationState.REQUEST_REJECTED);
+ } else {
+ mCall.setSessionModificationState(
+ Call.SessionModificationState.REQUEST_FAILED);
+ }
+ }
InCallVideoCallCallbackNotifier.getInstance().upgradeToVideoFail(status, mCall);
} else if (requestedProfile != null && responseProfile != null) {
boolean modifySucceeded = requestedProfile.getVideoState() ==
@@ -95,6 +108,8 @@ public class InCallVideoCallCallback extends VideoCall.Callback {
} else {
Log.d(this, "onSessionModifyResponseReceived request and response Profiles are null");
}
+ // Finally clear the outstanding request.
+ mCall.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
}
/**
diff --git a/InCallUI/src/com/android/incallui/StatusBarNotifier.java b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
index 86f997575..bc3687ced 100644
--- a/InCallUI/src/com/android/incallui/StatusBarNotifier.java
+++ b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
@@ -45,7 +45,9 @@ import com.android.incallui.InCallPresenter.InCallState;
/**
* This class adds Notifications to the status bar for the in-call experience.
*/
-public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
+public class StatusBarNotifier implements InCallPresenter.InCallStateListener,
+ CallList.CallUpdateListener {
+
// notification types
private static final int IN_CALL_NOTIFICATION = 1;
@@ -58,6 +60,8 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
private int mSavedContent = 0;
private Bitmap mSavedLargeIcon;
private String mSavedContentTitle;
+ private String mCallId = null;
+ private InCallState mInCallState;
public StatusBarNotifier(Context context, ContactInfoCache contactInfoCache) {
Preconditions.checkNotNull(context);
@@ -74,7 +78,7 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
@Override
public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
Log.d(this, "onStateChange");
-
+ mInCallState = newState;
updateNotification(newState, callList);
}
@@ -146,6 +150,12 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
final boolean isIncoming = (call.getState() == Call.State.INCOMING ||
call.getState() == Call.State.CALL_WAITING);
+ if (mCallId != null) {
+ CallList.getInstance().removeCallUpdateListener(mCallId, this);
+ }
+ mCallId = call.getId();
+ CallList.getInstance().addCallUpdateListener(call.getId(), this);
+
// we make a call to the contact info cache to query for supplemental data to what the
// call provides. This includes the contact name and photo.
// This callback will always get called immediately and synchronously with whatever data
@@ -574,4 +584,25 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
+ @Override
+ public void onCallChanged(Call call) {
+ // no-op
+ }
+
+ /**
+ * Responds to changes in the session modification state for the call by dismissing the
+ * status bar notification as required.
+ *
+ * @param sessionModificationState The new session modification state.
+ */
+ @Override
+ public void onSessionModificationStateChange(int sessionModificationState) {
+ if (sessionModificationState == Call.SessionModificationState.NO_REQUEST) {
+ if (mCallId != null) {
+ CallList.getInstance().removeCallUpdateListener(mCallId, this);
+ }
+
+ updateNotification(mInCallState, CallList.getInstance());
+ }
+ }
}
diff --git a/InCallUI/src/com/android/incallui/VideoCallFragment.java b/InCallUI/src/com/android/incallui/VideoCallFragment.java
index 6d70b4271..24e9e8d76 100644
--- a/InCallUI/src/com/android/incallui/VideoCallFragment.java
+++ b/InCallUI/src/com/android/incallui/VideoCallFragment.java
@@ -659,10 +659,12 @@ public class VideoCallFragment extends BaseFragment<VideoCallPresenter,
params.height = height;
preview.setLayoutParams(params);
- ViewGroup.LayoutParams containerParams = mPreviewVideoContainer.getLayoutParams();
- containerParams.width = width;
- containerParams.height = height;
- mPreviewVideoContainer.setLayoutParams(containerParams);
+ if (mPreviewVideoContainer != null) {
+ ViewGroup.LayoutParams containerParams = mPreviewVideoContainer.getLayoutParams();
+ containerParams.width = width;
+ containerParams.height = height;
+ mPreviewVideoContainer.setLayoutParams(containerParams);
+ }
// 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
diff --git a/InCallUI/src/com/android/incallui/VideoCallPresenter.java b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
index f145c24ca..87843f907 100644
--- a/InCallUI/src/com/android/incallui/VideoCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
@@ -22,7 +22,6 @@ import android.database.Cursor;
import android.graphics.Point;
import android.net.Uri;
import android.os.AsyncTask;
-import android.os.Handler;
import android.provider.ContactsContract;
import android.telecom.AudioState;
import android.telecom.CameraCapabilities;
@@ -31,6 +30,7 @@ import android.telecom.Connection.VideoProvider;
import android.telecom.InCallService.VideoCall;
import android.telecom.VideoProfile;
import android.view.Surface;
+import android.view.View;
import android.widget.ImageView;
import com.android.contacts.common.CallUtil;
@@ -163,10 +163,6 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
private static boolean mIsVideoMode = false;
- /** Handler which resets request state to NO_REQUEST after an interval. */
- private Handler mSessionModificationResetHandler;
- private static final long SESSION_MODIFICATION_RESET_DELAY_MS = 3000;
-
/**
* Contact photo manager to retrieve cached contact photo information.
*/
@@ -186,7 +182,6 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
mContext = context;
mMinimumVideoDimension = mContext.getResources().getDimension(
R.dimen.video_preview_small_dimension);
- mSessionModificationResetHandler = new Handler();
}
/**
@@ -933,8 +928,6 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
if (call == null) {
return;
}
-
- call.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
}
@Override
@@ -947,25 +940,6 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
if (call == null) {
return;
}
-
- if (status == VideoProvider.SESSION_MODIFY_REQUEST_TIMED_OUT) {
- call.setSessionModificationState(
- Call.SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT);
- } else {
- call.setSessionModificationState(Call.SessionModificationState.REQUEST_FAILED);
-
- final Call modifyCall = call;
- // Start handler to change state from REQUEST_FAILED to NO_REQUEST after an interval.
- mSessionModificationResetHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- if (modifyCall != null) {
- modifyCall
- .setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
- }
- }
- }, SESSION_MODIFICATION_RESET_DELAY_MS);
- }
}
@Override
@@ -1162,7 +1136,11 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
}
}
}
+ return null;
+ }
+ @Override
+ protected void onPostExecute(Void result) {
// If user profile information was found, issue an async request to load the user's
// profile photo.
if (mProfileInfo != null) {
@@ -1174,17 +1152,14 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
new ContactPhotoManager.DefaultImageRequest(mProfileInfo.name,
mProfileInfo.lookupKey, false /* isCircularPhoto */);
- mContactPhotoManager
- .loadDirectoryPhoto(ui.getPreviewPhotoView(),
+ ImageView photoView = ui.getPreviewPhotoView();
+ if (photoView == null) {
+ return;
+ }
+ mContactPhotoManager.loadDirectoryPhoto(photoView,
mProfileInfo.displayPhotoUri,
false /* darkTheme */, false /* isCircular */, imageRequest);
}
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- // No-op
}
};