summaryrefslogtreecommitdiff
path: root/InCallUI
diff options
context:
space:
mode:
authorAndrew Lee <anwlee@google.com>2014-08-11 14:44:18 -0700
committerAndrew Lee <anwlee@google.com>2014-08-12 10:19:05 -0700
commit9c98346835b8e902e0c2c11f14a35f4e91578e9f (patch)
tree83aefdcecd5d19d378f24b8dbd10c6896fdd2b27 /InCallUI
parentc4abc8aee5ff3d92f1ca255ba271f6f46ecd6cc8 (diff)
Add UI/functions to handle a video upgrade request.
+ Move session modification listener into the video call presenter. + Add new video accept/reject notification and full-screen UI. + Added "handling" which sends session modification response. Bug: 16657915 Change-Id: I35ff04e383d4938cbfb4e76677730f82557fd918
Diffstat (limited to 'InCallUI')
-rw-r--r--InCallUI/res/drawable/ic_lockscreen_decline_video.xml28
-rw-r--r--InCallUI/res/drawable/ic_lockscreen_decline_video_activated_layer.xml25
-rw-r--r--InCallUI/res/drawable/ic_lockscreen_decline_video_normal_layer.xml33
-rw-r--r--InCallUI/res/values/array.xml24
-rw-r--r--InCallUI/res/values/strings.xml6
-rw-r--r--InCallUI/src/com/android/incallui/AnswerFragment.java14
-rw-r--r--InCallUI/src/com/android/incallui/AnswerPresenter.java29
-rw-r--r--InCallUI/src/com/android/incallui/Call.java14
-rw-r--r--InCallUI/src/com/android/incallui/CallCardPresenter.java64
-rw-r--r--InCallUI/src/com/android/incallui/CallList.java15
-rw-r--r--InCallUI/src/com/android/incallui/GlowPadWrapper.java10
-rw-r--r--InCallUI/src/com/android/incallui/InCallApp.java8
-rw-r--r--InCallUI/src/com/android/incallui/InCallPresenter.java32
-rw-r--r--InCallUI/src/com/android/incallui/StatusBarNotifier.java67
-rw-r--r--InCallUI/src/com/android/incallui/VideoCallPresenter.java48
15 files changed, 333 insertions, 84 deletions
diff --git a/InCallUI/res/drawable/ic_lockscreen_decline_video.xml b/InCallUI/res/drawable/ic_lockscreen_decline_video.xml
new file mode 100644
index 000000000..cedd49757
--- /dev/null
+++ b/InCallUI/res/drawable/ic_lockscreen_decline_video.xml
@@ -0,0 +1,28 @@
+<?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
+ -->
+<!-- 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_decline_video_normal_layer"/>
+ <item
+ android:state_enabled="true" android:state_active="true" android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_decline_video_activated_layer" />
+ <item
+ android:state_enabled="true" android:state_active="false" android:state_focused="true"
+ android:drawable="@drawable/ic_lockscreen_decline_video_activated_layer" />
+</selector>
diff --git a/InCallUI/res/drawable/ic_lockscreen_decline_video_activated_layer.xml b/InCallUI/res/drawable/ic_lockscreen_decline_video_activated_layer.xml
new file mode 100644
index 000000000..63fe4cad8
--- /dev/null
+++ b/InCallUI/res/drawable/ic_lockscreen_decline_video_activated_layer.xml
@@ -0,0 +1,25 @@
+<?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
+ -->
+<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_toolbar_video_off"
+ android:tint="@color/glowpad_widget_active_color" />
+ </item>
+</layer-list>
diff --git a/InCallUI/res/drawable/ic_lockscreen_decline_video_normal_layer.xml b/InCallUI/res/drawable/ic_lockscreen_decline_video_normal_layer.xml
new file mode 100644
index 000000000..370d515e7
--- /dev/null
+++ b/InCallUI/res/drawable/ic_lockscreen_decline_video_normal_layer.xml
@@ -0,0 +1,33 @@
+<?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
+ -->
+<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_toolbar_video_off"
+ android:tint="@color/glowpad_call_widget_normal_tint" />
+ </item>
+</layer-list>
diff --git a/InCallUI/res/values/array.xml b/InCallUI/res/values/array.xml
index b741905dd..5270de1ac 100644
--- a/InCallUI/res/values/array.xml
+++ b/InCallUI/res/values/array.xml
@@ -111,4 +111,28 @@
<item>@string/description_direction_left</item>
<item>@string/description_direction_down</item>
</array>
+
+
+ <!-- For upgrade to video in an 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">
+ <item>@drawable/ic_lockscreen_answer_video</item>
+ <item>@null</item>
+ <item>@drawable/ic_lockscreen_decline</item>
+ <item>@null</item>"
+ </array>
+ <array name="incoming_call_widget_video_upgrade_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">
+ <item>@string/description_direction_right</item>
+ <item>@null</item>
+ <item>@string/description_direction_left</item>
+ <item>@null</item>
+ </array>
</resources>
diff --git a/InCallUI/res/values/strings.xml b/InCallUI/res/values/strings.xml
index 1ce382e42..964286aa0 100644
--- a/InCallUI/res/values/strings.xml
+++ b/InCallUI/res/values/strings.xml
@@ -504,6 +504,12 @@
<!-- Description of the target to answer a call as an audio call in the Slide unlock screen.
[CHAR LIMIT=NONE] -->
<string name="description_target_answer_audio_call">Answer as audio call</string>
+ <!-- Description of the target to accept a request to upgrade from an audio call to a video call.
+ [CHAR LIMIT=NONE] -->
+ <string name="description_target_accept_upgrade_to_video_request">Accept video request</string>
+ <!-- Description of the target to decline a request to upgrade from an audio call to a video call.
+ [CHAR LIMIT=NONE] -->
+ <string name="description_target_decline_upgrade_to_video_request">Decline video request</string>
<!-- Description of the up direction in which one can to slide the handle in the phone answer screen. [CHAR LIMIT=NONE] -->
<string name="description_direction_up">Slide up for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
diff --git a/InCallUI/src/com/android/incallui/AnswerFragment.java b/InCallUI/src/com/android/incallui/AnswerFragment.java
index db441237f..4fb79ac06 100644
--- a/InCallUI/src/com/android/incallui/AnswerFragment.java
+++ b/InCallUI/src/com/android/incallui/AnswerFragment.java
@@ -18,6 +18,7 @@ package com.android.incallui;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.Editable;
@@ -48,6 +49,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;
/**
* The popup showing the list of canned responses.
@@ -153,6 +155,14 @@ 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_AUDIO_WITHOUT_SMS:
default:
targetResourceId = R.array.incoming_call_widget_audio_without_sms_targets;
@@ -322,8 +332,8 @@ public class AnswerFragment extends BaseFragment<AnswerPresenter, AnswerPresente
}
@Override
- public void onAnswer(int videoState) {
- getPresenter().onAnswer(videoState);
+ public void onAnswer(int videoState, Context context) {
+ getPresenter().onAnswer(videoState, context);
}
@Override
diff --git a/InCallUI/src/com/android/incallui/AnswerPresenter.java b/InCallUI/src/com/android/incallui/AnswerPresenter.java
index 52112de42..0616b7e0a 100644
--- a/InCallUI/src/com/android/incallui/AnswerPresenter.java
+++ b/InCallUI/src/com/android/incallui/AnswerPresenter.java
@@ -16,6 +16,7 @@
package com.android.incallui;
+import android.content.Context;
import android.telecomm.CallCapabilities;
import java.util.List;
@@ -36,11 +37,15 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi>
super.onUiReady(ui);
final CallList calls = CallList.getInstance();
- final Call call = calls.getIncomingCall();
- // TODO: change so that answer presenter never starts up if it's not incoming.
+ Call call;
+ call = calls.getIncomingCall();
if (call != null) {
processIncomingCall(call);
}
+ call = calls.getVideoUpgradeRequestCall();
+ if (call != null) {
+ processVideoUpgradeRequestCall(call);
+ }
// Listen for incoming calls.
calls.addListener(this);
@@ -111,6 +116,17 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi>
}
}
+ private void processVideoUpgradeRequestCall(Call call) {
+ mCallId = call.getId();
+ mCall = call;
+
+ // Listen for call updates for the current call.
+ CallList.getInstance().addCallUpdateListener(mCallId, this);
+ getUi().showAnswerUi(true);
+
+ getUi().showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_UPGRADE_REQUEST);
+ }
+
@Override
public void onCallChanged(Call call) {
Log.d(this, "onCallStateChange() " + call + " " + this);
@@ -126,13 +142,18 @@ public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi>
}
}
- public void onAnswer(int videoState) {
+ public void onAnswer(int videoState, Context context) {
if (mCallId == null) {
return;
}
Log.d(this, "onAnswer " + mCallId);
- TelecommAdapter.getInstance().answerCall(mCall.getId(), videoState);
+ if (mCall.getSessionModificationState()
+ == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
+ InCallPresenter.getInstance().acceptUpgradeRequest(context);
+ } else {
+ TelecommAdapter.getInstance().answerCall(mCall.getId(), videoState);
+ }
}
/**
diff --git a/InCallUI/src/com/android/incallui/Call.java b/InCallUI/src/com/android/incallui/Call.java
index fcdf09223..2a97a3f5e 100644
--- a/InCallUI/src/com/android/incallui/Call.java
+++ b/InCallUI/src/com/android/incallui/Call.java
@@ -109,7 +109,8 @@ public final class Call {
public static class SessionModificationState {
public static final int NO_REQUEST = 0;
public static final int WAITING_FOR_RESPONSE = 1;
- public static final int REQUEST_FAILED = 1;
+ public static final int REQUEST_FAILED = 2;
+ public static final int RECEIVED_UPGRADE_TO_VIDEO_REQUEST = 3;
}
private static final String ID_PREFIX = Call.class.getSimpleName() + "_";
@@ -362,6 +363,17 @@ public final class Call {
}
}
+ public static boolean areSame(Call call1, Call call2) {
+ if (call1 == null && call2 == null) {
+ return true;
+ } else if (call1 == null || call2 == null) {
+ return false;
+ }
+
+ // otherwise compare call Ids
+ return call1.getId().equals(call2.getId());
+ }
+
public int getSessionModificationState() {
return mSessionModificationState;
}
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index 92412ea2e..e6ef71355 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -22,7 +22,6 @@ import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
import android.telecomm.CallCapabilities;
import android.telecomm.PhoneAccount;
import android.telecomm.PhoneAccountHandle;
@@ -54,18 +53,16 @@ import com.google.common.base.Preconditions;
*/
public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
implements InCallStateListener, IncomingCallListener, InCallDetailsListener,
- InCallEventListener, InCallVideoCallListenerNotifier.SessionModificationListener {
+ InCallEventListener {
private static final String TAG = CallCardPresenter.class.getSimpleName();
private static final long CALL_TIME_UPDATE_INTERVAL_MS = 1000;
- private static final long SESSION_MODIFICATION_RESET_DELAY_MS = 3000;
private Call mPrimary;
private Call mSecondary;
private ContactCacheEntry mPrimaryContactInfo;
private ContactCacheEntry mSecondaryContactInfo;
- private CallTimer mCallTimer;
- private Handler mSessionModificationResetHandler;
+ private CallTimer mCallT\imer;
private Context mContext;
private TelecommManager mTelecommManager;
@@ -104,7 +101,6 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
updateCallTime();
}
});
- mSessionModificationResetHandler = new Handler();
}
public void init(Context context, Call call) {
@@ -137,16 +133,12 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
InCallPresenter.getInstance().addIncomingCallListener(this);
InCallPresenter.getInstance().addDetailsListener(this);
InCallPresenter.getInstance().addInCallEventListener(this);
-
- InCallVideoCallListenerNotifier.getInstance().addSessionModificationListener(this);
}
@Override
public void onUiUnready(CallCardUi ui) {
super.onUiUnready(ui);
- InCallVideoCallListenerNotifier.getInstance().removeSessionModificationListener(this);
-
// stop getting call state changes
InCallPresenter.getInstance().removeListener(this);
InCallPresenter.getInstance().removeIncomingCallListener(this);
@@ -196,8 +188,9 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
final boolean outgoingCallReady = newState == InCallState.OUTGOING &&
oldState == InCallState.PENDING_OUTGOING;
- final boolean primaryChanged = !areCallsSame(mPrimary, primary) || outgoingCallReady;
- final boolean secondaryChanged = !areCallsSame(mSecondary, secondary);
+ final boolean primaryChanged = !Call.areSame(mPrimary, primary);
+ final boolean secondaryChanged = !Call.areSame(mSecondary, secondary);
+
mSecondary = secondary;
mPrimary = primary;
@@ -364,53 +357,6 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
TelecommAdapter.getInstance().phoneAccountClicked(mPrimary.getId());
}
- @Override
- public void onUpgradeToVideoRequest(Call call) {
- // Implementing to satsify interface.
- }
-
- @Override
- public void onUpgradeToVideoSuccess(Call call) {
- if (mPrimary == null || !areCallsSame(mPrimary, call)) {
- return;
- }
-
- mPrimary.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
- }
-
- @Override
- public void onUpgradeToVideoFail(Call call) {
- if (mPrimary == null || !areCallsSame(mPrimary, call)) {
- return;
- }
-
- call.setSessionModificationState(Call.SessionModificationState.REQUEST_FAILED);
-
- // Start handler to change state from REQUEST_FAILED to NO_REQUEST after an interval.
- mSessionModificationResetHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- mPrimary.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
- }
- }, SESSION_MODIFICATION_RESET_DELAY_MS);
- }
-
- @Override
- public void onDowngradeToAudio(Call call) {
- // Implementing to satsify interface.
- }
-
- private boolean areCallsSame(Call call1, Call call2) {
- if (call1 == null && call2 == null) {
- return true;
- } else if (call1 == null || call2 == null) {
- return false;
- }
-
- // otherwise compare call Ids
- return call1.getId().equals(call2.getId());
- }
-
private void maybeStartSearch(Call call, boolean isPrimary) {
// no need to start search for conference calls which show generic info.
if (call != null && !call.isConferenceCall()) {
diff --git a/InCallUI/src/com/android/incallui/CallList.java b/InCallUI/src/com/android/incallui/CallList.java
index becb411ca..66103e6ff 100644
--- a/InCallUI/src/com/android/incallui/CallList.java
+++ b/InCallUI/src/com/android/incallui/CallList.java
@@ -273,6 +273,21 @@ public class CallList implements InCallPhoneListener {
return result;
}
+ /**
+ * Returns the first call found in the call map with the specified call modification state.
+ * @param state The session modification state to search for.
+ * @return The first call with the specified state.
+ */
+ public Call getVideoUpgradeRequestCall() {
+ for(Call call : mCallById.values()) {
+ if (call.getSessionModificationState() ==
+ Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
+ return call;
+ }
+ }
+ return null;
+ }
+
public Call getCallById(String callId) {
return mCallById.get(callId);
}
diff --git a/InCallUI/src/com/android/incallui/GlowPadWrapper.java b/InCallUI/src/com/android/incallui/GlowPadWrapper.java
index 859cd64bd..1617d06bc 100644
--- a/InCallUI/src/com/android/incallui/GlowPadWrapper.java
+++ b/InCallUI/src/com/android/incallui/GlowPadWrapper.java
@@ -112,7 +112,7 @@ public class GlowPadWrapper extends GlowPadView implements GlowPadView.OnTrigger
final int resId = getResourceIdForTarget(target);
switch (resId) {
case R.drawable.ic_lockscreen_answer:
- mAnswerListener.onAnswer(VideoCallProfile.VideoState.AUDIO_ONLY);
+ mAnswerListener.onAnswer(VideoCallProfile.VideoState.AUDIO_ONLY, getContext());
mTargetTriggered = true;
break;
case R.drawable.ic_lockscreen_decline:
@@ -124,7 +124,11 @@ public class GlowPadWrapper extends GlowPadView implements GlowPadView.OnTrigger
mTargetTriggered = true;
break;
case R.drawable.ic_videocam:
- mAnswerListener.onAnswer(VideoCallProfile.VideoState.BIDIRECTIONAL);
+ mAnswerListener.onAnswer(VideoCallProfile.VideoState.BIDIRECTIONAL, getContext());
+ mTargetTriggered = true;
+ break;
+ case R.drawable.ic_toolbar_video_off:
+ InCallPresenter.getInstance().declineUpgradeRequest(getContext());
mTargetTriggered = true;
break;
default:
@@ -148,7 +152,7 @@ public class GlowPadWrapper extends GlowPadView implements GlowPadView.OnTrigger
}
public interface AnswerListener {
- void onAnswer(int videoState);
+ void onAnswer(int videoState, Context context);
void onDecline();
void onText();
}
diff --git a/InCallUI/src/com/android/incallui/InCallApp.java b/InCallUI/src/com/android/incallui/InCallApp.java
index c7bb4fb2a..78faf1f2b 100644
--- a/InCallUI/src/com/android/incallui/InCallApp.java
+++ b/InCallUI/src/com/android/incallui/InCallApp.java
@@ -41,6 +41,10 @@ public class InCallApp extends Application {
"com.android.incallui.ACTION_ANSWER_VIDEO_INCOMING_CALL";
public static final String ACTION_ANSWER_VOICE_INCOMING_CALL =
"com.android.incallui.ACTION_ANSWER_VOICE_INCOMING_CALL";
+ public static final String ACTION_ACCEPT_VIDEO_UPGRADE_REQUEST =
+ "com.android.incallui.ACTION_ACCEPT_VIDEO_UPGRADE_REQUEST";
+ public static final String ACTION_DECLINE_VIDEO_UPGRADE_REQUEST =
+ "com.android.incallui.ACTION_DECLINE_VIDEO_UPGRADE_REQUEST";
public InCallApp() {
}
@@ -76,6 +80,10 @@ public class InCallApp extends Application {
InCallPresenter.getInstance().declineIncomingCall(context);
} else if (action.equals(ACTION_HANG_UP_ONGOING_CALL)) {
InCallPresenter.getInstance().hangUpOngoingCall(context);
+ } else if (action.equals(ACTION_ACCEPT_VIDEO_UPGRADE_REQUEST)) {
+ InCallPresenter.getInstance().acceptUpgradeRequest(context);
+ } else if (action.equals(ACTION_DECLINE_VIDEO_UPGRADE_REQUEST)) {
+ InCallPresenter.getInstance().declineUpgradeRequest(context);
}
}
}
diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java
index cf43fbd66..79085acfe 100644
--- a/InCallUI/src/com/android/incallui/InCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/InCallPresenter.java
@@ -525,6 +525,38 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
}
}
+ public void acceptUpgradeRequest(Context context) {
+ // Bail if we have been shut down and the call list is null.
+ if (mCallList == null) {
+ StatusBarNotifier.clearInCallNotification(context);
+ return;
+ }
+
+ Call call = mCallList.getVideoUpgradeRequestCall();
+ if (call != null) {
+ VideoCallProfile videoProfile =
+ new VideoCallProfile(VideoCallProfile.VideoState.BIDIRECTIONAL);
+ call.getVideoCall().sendSessionModifyResponse(videoProfile);
+ call.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
+ }
+ }
+
+ public void declineUpgradeRequest(Context context) {
+ // Bail if we have been shut down and the call list is null.
+ if (mCallList == null) {
+ StatusBarNotifier.clearInCallNotification(context);
+ return;
+ }
+
+ Call call = mCallList.getVideoUpgradeRequestCall();
+ if (call != null) {
+ VideoCallProfile videoProfile =
+ new VideoCallProfile(VideoCallProfile.VideoState.AUDIO_ONLY);
+ call.getVideoCall().sendSessionModifyResponse(videoProfile);
+ call.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
+ }
+ }
+
/**
* Returns true if the incall app is the foreground application.
*/
diff --git a/InCallUI/src/com/android/incallui/StatusBarNotifier.java b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
index f88d2b5c6..7efaa12b8 100644
--- a/InCallUI/src/com/android/incallui/StatusBarNotifier.java
+++ b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
@@ -258,12 +258,15 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
final int state = call.getState();
final boolean isConference = call.isConferenceCall();
+ final boolean isVideoUpgradeRequest = call.getSessionModificationState()
+ == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST;
+
+ // Check if data has changed; if nothing is different, don't issue another notification.
final int iconResId = getIconToDisplay(call);
final Bitmap largeIcon = getLargeIconToDisplay(contactInfo, isConference);
final int contentResId = getContentString(call);
final String contentTitle = getContentTitle(contactInfo, isConference);
- // If we checked and found that nothing is different, dont issue another notification.
if (!checkForChangeAndSaveData(iconResId, contentResId, largeIcon, contentTitle, state)) {
return;
}
@@ -283,12 +286,33 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
configureFullScreenIntent(builder, inCallPendingIntent, call);
}
- // set the content
+ // Set the content
builder.setContentText(mContext.getString(contentResId));
builder.setSmallIcon(iconResId);
builder.setContentTitle(contentTitle);
builder.setLargeIcon(largeIcon);
+ if (isVideoUpgradeRequest) {
+ builder.setUsesChronometer(false);
+ addDismissUpgradeRequestAction(builder);
+ addAcceptUpgradeRequestAction(builder);
+ } else {
+ createIncomingCallNotification(call, state, builder);
+ }
+
+ addPersonReference(builder, contactInfo, call);
+
+ /*
+ * Fire off the notification
+ */
+ Notification notification = builder.build();
+ Log.d(this, "Notifying IN_CALL_NOTIFICATION: " + notification);
+ mNotificationManager.notify(IN_CALL_NOTIFICATION, notification);
+ mIsShowingNotification = true;
+ }
+
+ private void createIncomingCallNotification(
+ Call call, int state, Notification.Builder builder) {
if (state == Call.State.ACTIVE) {
builder.setUsesChronometer(true);
builder.setWhen(call.getConnectTimeMillis());
@@ -310,16 +334,6 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
addAnswerAction(builder);
}
}
-
- addPersonReference(builder, contactInfo, call);
-
- /*
- * Fire off the notification
- */
- Notification notification = builder.build();
- Log.d(this, "Notifying IN_CALL_NOTIFICATION: " + notification);
- mNotificationManager.notify(IN_CALL_NOTIFICATION, notification);
- mIsShowingNotification = true;
}
/**
@@ -422,6 +436,9 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
// display that regardless of the state of the other calls.
if (call.getState() == Call.State.ONHOLD) {
return R.drawable.stat_sys_phone_call_on_hold;
+ } else if (call.getSessionModificationState()
+ == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
+ return R.drawable.ic_videocam;
}
return R.drawable.fab_ic_call;
}
@@ -434,12 +451,13 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
if (call.getState() == Call.State.INCOMING || call.getState() == Call.State.CALL_WAITING) {
resId = R.string.notification_incoming_call;
-
} else if (call.getState() == Call.State.ONHOLD) {
resId = R.string.notification_on_hold;
-
} else if (Call.State.isDialing(call.getState())) {
resId = R.string.notification_dialing;
+ } else if (call.getSessionModificationState()
+ == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
+ resId = R.string.notification_requesting_video_call;
}
return resId;
@@ -457,6 +475,9 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
call = callList.getOutgoingCall();
}
if (call == null) {
+ call = callList.getVideoUpgradeRequestCall();
+ }
+ if (call == null) {
call = callList.getActiveOrBackgroundCall();
}
return call;
@@ -512,6 +533,24 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
answerVoicePendingIntent);
}
+ private void addAcceptUpgradeRequestAction(Notification.Builder builder) {
+ Log.i(this, "Will show \"accept\" action in the incoming call Notification");
+
+ PendingIntent acceptVideoPendingIntent = createNotificationPendingIntent(
+ mContext, InCallApp.ACTION_ANSWER_VOICE_INCOMING_CALL);
+ builder.addAction(0, mContext.getText(R.string.notification_action_accept),
+ acceptVideoPendingIntent);
+ }
+
+ private void addDismissUpgradeRequestAction(Notification.Builder builder) {
+ Log.i(this, "Will show \"dismiss\" action in the incoming call Notification");
+
+ PendingIntent declineVideoPendingIntent = createNotificationPendingIntent(
+ mContext, InCallApp.ACTION_ANSWER_VOICE_INCOMING_CALL);
+ builder.addAction(0, mContext.getText(R.string.notification_action_dismiss),
+ declineVideoPendingIntent);
+ }
+
/**
* Adds fullscreen intent to the builder.
*/
diff --git a/InCallUI/src/com/android/incallui/VideoCallPresenter.java b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
index 025a863e2..73947e521 100644
--- a/InCallUI/src/com/android/incallui/VideoCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
@@ -18,6 +18,7 @@ package com.android.incallui;
import android.content.Context;
import android.content.res.Configuration;
+import android.os.Handler;
import android.telecomm.CallAudioState;
import android.telecomm.InCallService.VideoCall;
import android.view.Surface;
@@ -56,7 +57,8 @@ import java.util.Objects;
*/
public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi> implements
IncomingCallListener, InCallOrientationListener, InCallStateListener,
- InCallDetailsListener, SurfaceChangeListener, VideoEventListener {
+ InCallDetailsListener, SurfaceChangeListener, VideoEventListener,
+ InCallVideoCallListenerNotifier.SessionModificationListener {
/**
* Determines the device orientation (portrait/lanscape).
@@ -145,6 +147,10 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
*/
private int mPreVideoAudioMode = AudioModeProvider.AUDIO_MODE_INVALID;
+ /** Handler which resets request state to NO_REQUEST after an interval. */
+ private Handler mSessionModificationResetHandler;
+ private static final long SESSION_MODIFICATION_RESET_DELAY_MS = 3000;
+
/**
* Initializes the presenter.
*
@@ -154,6 +160,7 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
mContext = Preconditions.checkNotNull(context);
mMinimumVideoDimension = mContext.getResources().getDimension(
R.dimen.video_preview_small_dimension);
+ mSessionModificationResetHandler = new Handler();
}
/**
@@ -173,6 +180,7 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
// Register for surface and video events from {@link InCallVideoCallListener}s.
InCallVideoCallListenerNotifier.getInstance().addSurfaceChangeListener(this);
InCallVideoCallListenerNotifier.getInstance().addVideoEventListener(this);
+ InCallVideoCallListenerNotifier.getInstance().addSessionModificationListener(this);
mInCallCameraManager = InCallPresenter.getInstance().getInCallCameraManager();
mIsVideoCall = false;
@@ -192,6 +200,7 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
InCallPresenter.getInstance().removeOrientationListener(this);
InCallVideoCallListenerNotifier.getInstance().removeSurfaceChangeListener(this);
InCallVideoCallListenerNotifier.getInstance().removeVideoEventListener(this);
+ InCallVideoCallListenerNotifier.getInstance().removeSessionModificationListener(this);
mInCallCameraManager = null;
}
@@ -516,6 +525,43 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
mDeviceOrientation = orientation;
}
+ @Override
+ public void onUpgradeToVideoRequest(Call call) {
+ mPrimaryCall.setSessionModificationState(
+ Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST);
+ }
+
+ @Override
+ public void onUpgradeToVideoSuccess(Call call) {
+ if (mPrimaryCall == null || !Call.areSame(mPrimaryCall, call)) {
+ return;
+ }
+
+ mPrimaryCall.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
+ }
+
+ @Override
+ public void onUpgradeToVideoFail(Call call) {
+ if (mPrimaryCall == null || !Call.areSame(mPrimaryCall, call)) {
+ return;
+ }
+
+ call.setSessionModificationState(Call.SessionModificationState.REQUEST_FAILED);
+
+ // Start handler to change state from REQUEST_FAILED to NO_REQUEST after an interval.
+ mSessionModificationResetHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mPrimaryCall.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
+ }
+ }, SESSION_MODIFICATION_RESET_DELAY_MS);
+ }
+
+ @Override
+ public void onDowngradeToAudio(Call call) {
+ // Implementing to satsify interface.
+ }
+
/**
* Sets the preview surface size based on the current device orientation.
* See: {@link Configuration.ORIENTATION_LANDSCAPE}, {@link Configuration.ORIENTATION_PORTRAIT}