aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/java/com/android/ims/ImsCall.java10
-rw-r--r--src/java/com/android/ims/ImsConnectionStateListener.java11
-rw-r--r--src/java/com/android/ims/ImsManager.java10
-rw-r--r--src/java/com/android/ims/internal/ImsVideoCallProviderWrapper.java105
-rw-r--r--src/java/com/android/ims/internal/VideoPauseTracker.java9
5 files changed, 120 insertions, 25 deletions
diff --git a/src/java/com/android/ims/ImsCall.java b/src/java/com/android/ims/ImsCall.java
index 221b4c0d..ad289fd1 100644
--- a/src/java/com/android/ims/ImsCall.java
+++ b/src/java/com/android/ims/ImsCall.java
@@ -1881,13 +1881,16 @@ public class ImsCall implements ICall {
setIsMerged(playDisconnectTone);
mSessionEndDuringMerge = true;
String reasonInfo;
+ int reasonCode = ImsReasonInfo.CODE_UNSPECIFIED;
if (playDisconnectTone) {
+ reasonCode = ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE;
reasonInfo = "Call ended by network";
} else {
+ reasonCode = ImsReasonInfo.CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE;
reasonInfo = "Call ended during conference merge process.";
}
mSessionEndDuringMergeReasonInfo = new ImsReasonInfo(
- ImsReasonInfo.CODE_UNSPECIFIED, 0, reasonInfo);
+ reasonCode, 0, reasonInfo);
}
}
@@ -3343,6 +3346,7 @@ public class ImsCall implements ICall {
sb.append(" mute:");
sb.append(isMuted() ? "Y" : "N");
if (mCallProfile != null) {
+ sb.append(" mCallProfile:" + mCallProfile);
sb.append(" tech:");
sb.append(mCallProfile.getCallExtra(ImsCallProfile.EXTRA_CALL_RAT_TYPE));
}
@@ -3367,8 +3371,12 @@ public class ImsCall implements ICall {
sb.append(isConferenceHost() ? "Y" : "N");
sb.append(" buried term:");
sb.append(mSessionEndDuringMerge ? "Y" : "N");
+ sb.append(" isVideo: ");
+ sb.append(isVideoCall() ? "Y" : "N");
sb.append(" wasVideo: ");
sb.append(mWasVideoCall ? "Y" : "N");
+ sb.append(" isWifi: ");
+ sb.append(isWifiCall() ? "Y" : "N");
sb.append(" session:");
sb.append(mSession);
sb.append(" transientSession:");
diff --git a/src/java/com/android/ims/ImsConnectionStateListener.java b/src/java/com/android/ims/ImsConnectionStateListener.java
index f281df1f..4425854b 100644
--- a/src/java/com/android/ims/ImsConnectionStateListener.java
+++ b/src/java/com/android/ims/ImsConnectionStateListener.java
@@ -27,13 +27,6 @@ import android.net.Uri;
*/
public class ImsConnectionStateListener {
/**
- * Called when the device is connected to the IMS network.
- */
- public void onImsConnected() {
- // no-op
- }
-
- /**
* Called when the device is connected to the IMS network with {@param imsRadioTech}.
*/
public void onImsConnected(int imsRadioTech) {
@@ -41,9 +34,9 @@ public class ImsConnectionStateListener {
}
/**
- * Called when the device is trying to connect to the IMS network.
+ * Called when the device is trying to connect to the IMS network with {@param imsRadioTech}.
*/
- public void onImsProgressing() {
+ public void onImsProgressing(int imsRadioTech) {
// no-op
}
diff --git a/src/java/com/android/ims/ImsManager.java b/src/java/com/android/ims/ImsManager.java
index 7c258291..82f2c68f 100644
--- a/src/java/com/android/ims/ImsManager.java
+++ b/src/java/com/android/ims/ImsManager.java
@@ -32,6 +32,7 @@ import android.provider.Settings;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
+import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsServiceProxy;
@@ -2233,7 +2234,7 @@ public class ImsManager {
}
if (mListener != null) {
- mListener.onImsConnected();
+ mListener.onImsConnected(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
}
}
@@ -2244,7 +2245,7 @@ public class ImsManager {
}
if (mListener != null) {
- mListener.onImsProgressing();
+ mListener.onImsProgressing(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
}
}
@@ -2257,7 +2258,6 @@ public class ImsManager {
}
if (mListener != null) {
- mListener.onImsConnected();
mListener.onImsConnected(imsRadioTech);
}
}
@@ -2271,7 +2271,7 @@ public class ImsManager {
}
if (mListener != null) {
- mListener.onImsProgressing();
+ mListener.onImsProgressing(imsRadioTech);
}
}
@@ -2316,7 +2316,7 @@ public class ImsManager {
serviceClass + ", event=" + event);
if (mListener != null) {
- mListener.onImsConnected();
+ mListener.onImsConnected(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
}
}
diff --git a/src/java/com/android/ims/internal/ImsVideoCallProviderWrapper.java b/src/java/com/android/ims/internal/ImsVideoCallProviderWrapper.java
index fcb9e09b..d6da824f 100644
--- a/src/java/com/android/ims/internal/ImsVideoCallProviderWrapper.java
+++ b/src/java/com/android/ims/internal/ImsVideoCallProviderWrapper.java
@@ -29,6 +29,7 @@ import android.telecom.Log;
import android.telecom.VideoProfile;
import android.view.Surface;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
import java.util.Collections;
@@ -67,6 +68,7 @@ public class ImsVideoCallProviderWrapper extends Connection.VideoProvider {
private final Set<ImsVideoProviderWrapperCallback> mCallbacks = Collections.newSetFromMap(
new ConcurrentHashMap<ImsVideoProviderWrapperCallback, Boolean>(8, 0.9f, 1));
private VideoPauseTracker mVideoPauseTracker = new VideoPauseTracker();
+ private boolean mUseVideoPauseWorkaround = false;
private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
@Override
@@ -207,13 +209,26 @@ public class ImsVideoCallProviderWrapper extends Connection.VideoProvider {
*
* @param VideoProvider
*/
- public ImsVideoCallProviderWrapper(IImsVideoCallProvider VideoProvider)
+ public ImsVideoCallProviderWrapper(IImsVideoCallProvider videoProvider)
throws RemoteException {
- mVideoCallProvider = VideoProvider;
- mVideoCallProvider.asBinder().linkToDeath(mDeathRecipient, 0);
- mBinder = new ImsVideoCallCallback();
- mVideoCallProvider.setCallback(mBinder);
+ mVideoCallProvider = videoProvider;
+ if (videoProvider != null) {
+ mVideoCallProvider.asBinder().linkToDeath(mDeathRecipient, 0);
+
+ mBinder = new ImsVideoCallCallback();
+ mVideoCallProvider.setCallback(mBinder);
+ } else {
+ mBinder = null;
+ }
+ }
+
+ @VisibleForTesting
+ public ImsVideoCallProviderWrapper(IImsVideoCallProvider videoProvider,
+ VideoPauseTracker videoPauseTracker)
+ throws RemoteException {
+ this(videoProvider);
+ mVideoPauseTracker = videoPauseTracker;
}
/** @inheritDoc */
@@ -323,7 +338,8 @@ public class ImsVideoCallProviderWrapper extends Connection.VideoProvider {
* @param to The to video state.
* @return {@code true} if a pause was requested.
*/
- private static boolean isPauseRequest(int from, int to) {
+ @VisibleForTesting
+ public static boolean isPauseRequest(int from, int to) {
boolean fromPaused = VideoProfile.isPaused(from);
boolean toPaused = VideoProfile.isPaused(to);
@@ -337,7 +353,8 @@ public class ImsVideoCallProviderWrapper extends Connection.VideoProvider {
* @param to The to video state.
* @return {@code true} if a resume was requested.
*/
- private static boolean isResumeRequest(int from, int to) {
+ @VisibleForTesting
+ public static boolean isResumeRequest(int from, int to) {
boolean fromPaused = VideoProfile.isPaused(from);
boolean toPaused = VideoProfile.isPaused(to);
@@ -345,6 +362,30 @@ public class ImsVideoCallProviderWrapper extends Connection.VideoProvider {
}
/**
+ * Determines if this request includes turning the camera off (ie turning off transmission).
+ * @param from the from video state.
+ * @param to the to video state.
+ * @return true if the state change disables the user's camera.
+ */
+ @VisibleForTesting
+ public static boolean isTurnOffCameraRequest(int from, int to) {
+ return VideoProfile.isTransmissionEnabled(from)
+ && !VideoProfile.isTransmissionEnabled(to);
+ }
+
+ /**
+ * Determines if this request includes turning the camera on (ie turning on transmission).
+ * @param from the from video state.
+ * @param to the to video state.
+ * @return true if the state change enables the user's camera.
+ */
+ @VisibleForTesting
+ public static boolean isTurnOnCameraRequest(int from, int to) {
+ return !VideoProfile.isTransmissionEnabled(from)
+ && VideoProfile.isTransmissionEnabled(to);
+ }
+
+ /**
* Filters incoming pause and resume requests based on whether there are other active pause or
* resume requests at the current time.
*
@@ -361,7 +402,8 @@ public class ImsVideoCallProviderWrapper extends Connection.VideoProvider {
* @return The new toProfile, with the pause bit set or unset based on whether we should
* actually pause or resume the video at the current time.
*/
- private VideoProfile maybeFilterPauseResume(VideoProfile fromProfile, VideoProfile toProfile,
+ @VisibleForTesting
+ public VideoProfile maybeFilterPauseResume(VideoProfile fromProfile, VideoProfile toProfile,
int source) {
int fromVideoState = fromProfile.getVideoState();
int toVideoState = toProfile.getVideoState();
@@ -381,7 +423,9 @@ public class ImsVideoCallProviderWrapper extends Connection.VideoProvider {
boolean isPauseRequest = isPauseRequest(fromVideoState, toVideoState) || isPauseSpecialCase;
boolean isResumeRequest = isResumeRequest(fromVideoState, toVideoState);
if (isPauseRequest) {
- Log.i(this, "maybeFilterPauseResume: isPauseRequest");
+ Log.i(this, "maybeFilterPauseResume: isPauseRequest (from=%s, to=%s)",
+ VideoProfile.videoStateToString(fromVideoState),
+ VideoProfile.videoStateToString(toVideoState));
// Check if we have already paused the video in the past.
if (!mVideoPauseTracker.shouldPauseVideoFor(source) && !isPauseSpecialCase) {
// Note: We don't want to remove the "pause" in the "special case" scenario. If we
@@ -393,7 +437,29 @@ public class ImsVideoCallProviderWrapper extends Connection.VideoProvider {
toProfile = new VideoProfile(toVideoState, toProfile.getQuality());
}
} else if (isResumeRequest) {
- Log.i(this, "maybeFilterPauseResume: isResumeRequest");
+ boolean isTurnOffCameraRequest = isTurnOffCameraRequest(fromVideoState, toVideoState);
+ boolean isTurnOnCameraRequest = isTurnOnCameraRequest(fromVideoState, toVideoState);
+ // TODO: Fix vendor code so that this isn't required.
+ // Some vendors do not properly handle turning the camera on/off when the video is
+ // in paused state.
+ // If the request is to turn on/off the camera, it might be in the unfortunate format:
+ // FROM: Audio Tx Rx Pause TO: Audio Rx
+ // FROM: Audio Rx Pause TO: Audio Rx Tx
+ // If this is the case, we should not treat this request as a resume request as well.
+ // Ideally the IMS stack should treat a turn off camera request as:
+ // FROM: Audio Tx Rx Pause TO: Audio Rx Pause
+ // FROM: Audio Rx Pause TO: Audio Rx Tx Pause
+ // Unfortunately, it does not. ¯\_(ツ)_/¯
+ if (mUseVideoPauseWorkaround && (isTurnOffCameraRequest || isTurnOnCameraRequest)) {
+ Log.i(this, "maybeFilterPauseResume: isResumeRequest, but camera turning on/off so "
+ + "skipping (from=%s, to=%s)",
+ VideoProfile.videoStateToString(fromVideoState),
+ VideoProfile.videoStateToString(toVideoState));
+ return toProfile;
+ }
+ Log.i(this, "maybeFilterPauseResume: isResumeRequest (from=%s, to=%s)",
+ VideoProfile.videoStateToString(fromVideoState),
+ VideoProfile.videoStateToString(toVideoState));
// Check if we should remain paused (other pause requests pending).
if (!mVideoPauseTracker.shouldResumeVideoFor(source)) {
// There are other pause requests from other sources which are still active, so we
@@ -465,4 +531,23 @@ public class ImsVideoCallProviderWrapper extends Connection.VideoProvider {
public boolean wasVideoPausedFromSource(int source) {
return mVideoPauseTracker.wasVideoPausedFromSource(source);
}
+
+ public void setUseVideoPauseWorkaround(boolean useVideoPauseWorkaround) {
+ mUseVideoPauseWorkaround = useVideoPauseWorkaround;
+ }
+
+ /**
+ * Called by {@code ImsPhoneConnection} when there is a change to the video state of the call.
+ * Informs the video pause tracker that the video is no longer paused. This ensures that
+ * subsequent pause requests are not filtered out.
+ *
+ * @param newVideoState The new video state.
+ */
+ public void onVideoStateChanged(int newVideoState) {
+ if (mVideoPauseTracker.isPaused() && !VideoProfile.isPaused(newVideoState)) {
+ Log.i(this, "onVideoStateChanged: newVideoState=%s, clearing pending pause requests.",
+ VideoProfile.videoStateToString(newVideoState));
+ mVideoPauseTracker.clearPauseRequests();
+ }
+ }
}
diff --git a/src/java/com/android/ims/internal/VideoPauseTracker.java b/src/java/com/android/ims/internal/VideoPauseTracker.java
index d37f7fa8..a23c5901 100644
--- a/src/java/com/android/ims/internal/VideoPauseTracker.java
+++ b/src/java/com/android/ims/internal/VideoPauseTracker.java
@@ -150,6 +150,15 @@ public class VideoPauseTracker {
}
/**
+ * Clears pending pause requests for the tracker.
+ */
+ public void clearPauseRequests() {
+ synchronized (mPauseRequestsLock) {
+ mPauseRequests.clear();
+ }
+ }
+
+ /**
* Returns a string equivalent of a {@code SOURCE_*} constant.
*
* @param source A {@code SOURCE_*} constant.