summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBodam Nam <bodamnam@google.com>2023-04-11 07:24:46 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2023-04-11 07:24:46 +0000
commit92337d569130be377615fb8421adbced82f49811 (patch)
tree48e6c31c93d86e94b8990075bfaf1f34ea3684fe
parentffff185c086184397aac56637cfe2e5f74af065e (diff)
parent1b233d3498e685039b709fa89820e536b231688b (diff)
downloadImsMedia-92337d569130be377615fb8421adbced82f49811.tar.gz
Merge "Implementation of video downgrade opreration API" into udc-dev
-rw-r--r--framework/src/android/telephony/imsmedia/IImsVideoSessionCallback.aidl2
-rw-r--r--framework/src/android/telephony/imsmedia/MediaQualityThreshold.java26
-rw-r--r--framework/src/android/telephony/imsmedia/VideoSessionCallback.java11
-rw-r--r--service/src/com/android/telephony/imsmedia/Utils.java1
-rw-r--r--service/src/com/android/telephony/imsmedia/VideoListener.java2
-rw-r--r--service/src/com/android/telephony/imsmedia/VideoSession.java10
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/include/MediaQualityThreshold.h9
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/src/MediaQualityThreshold.cpp22
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/ImsMediaDefine.h3
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/VideoStreamGraphRtpTx.h1
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaVideoSource.h2
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/nodes/IVideoSourceNode.h10
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoManager.cpp7
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoSession.cpp6
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTx.cpp17
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp7
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/IVideoSourceNode.cpp21
-rw-r--r--test/app/ImsMediaTestingApp/app/src/main/java/com/example/imsmediatestingapp/MainActivity.java56
-rw-r--r--tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityThresholdTest.cpp6
-rw-r--r--tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTxTest.cpp6
-rw-r--r--tests/unit/src/com/android/telephony/imsmedia/AudioOffloadTest.java3
-rw-r--r--tests/unit/src/com/android/telephony/imsmedia/MediaQualityThresholdTest.java20
-rw-r--r--tests/unit/src/com/android/telephony/imsmedia/VideoListenerTest.java6
-rw-r--r--tests/unit/src/com/android/telephony/imsmedia/VideoSessionTest.java6
24 files changed, 208 insertions, 52 deletions
diff --git a/framework/src/android/telephony/imsmedia/IImsVideoSessionCallback.aidl b/framework/src/android/telephony/imsmedia/IImsVideoSessionCallback.aidl
index 8de33a39..b48e560d 100644
--- a/framework/src/android/telephony/imsmedia/IImsVideoSessionCallback.aidl
+++ b/framework/src/android/telephony/imsmedia/IImsVideoSessionCallback.aidl
@@ -35,6 +35,6 @@ oneway interface IImsVideoSessionCallback {
void onPeerDimensionChanged(in int width, in int height);
void onHeaderExtensionReceived(in List<RtpHeaderExtension> extensions);
void notifyMediaInactivity(int packetType);
- void notifyPacketLoss(int packetLossPercentage);
+ void notifyBitrate(int bitate);
void notifyVideoDataUsage(long bytes);
}
diff --git a/framework/src/android/telephony/imsmedia/MediaQualityThreshold.java b/framework/src/android/telephony/imsmedia/MediaQualityThreshold.java
index 3f38e89a..42024a87 100644
--- a/framework/src/android/telephony/imsmedia/MediaQualityThreshold.java
+++ b/framework/src/android/telephony/imsmedia/MediaQualityThreshold.java
@@ -38,6 +38,7 @@ public final class MediaQualityThreshold implements Parcelable {
private final int[] mRtpPacketLossRate;
private final int[] mRtpJitterMillis;
private final boolean mNotifyCurrentStatus;
+ private final int mVideoBitrateBps;
/** @hide **/
public MediaQualityThreshold(Parcel in) {
@@ -60,6 +61,7 @@ public final class MediaQualityThreshold implements Parcelable {
mRtpJitterMillis[i] = in.readInt();
}
mNotifyCurrentStatus = in.readBoolean();
+ mVideoBitrateBps = in.readInt();
}
/** @hide **/
@@ -74,6 +76,7 @@ public final class MediaQualityThreshold implements Parcelable {
mRtpJitterMillis = Arrays.copyOf(builder.mRtpJitterMillis,
builder.mRtpJitterMillis.length);
mNotifyCurrentStatus = builder.mNotifyCurrentStatus;
+ mVideoBitrateBps = builder.mVideoBitrateBps;
}
/** @hide **/
@@ -111,6 +114,10 @@ public final class MediaQualityThreshold implements Parcelable {
return mNotifyCurrentStatus;
}
+ public int getVideoBitrateBps() {
+ return mVideoBitrateBps;
+ }
+
@NonNull
@Override
public String toString() {
@@ -122,6 +129,7 @@ public final class MediaQualityThreshold implements Parcelable {
+ ", mRtpPacketLossRate=" + Arrays.toString(mRtpPacketLossRate)
+ ", mRtpJitterMillis=" + Arrays.toString(mRtpJitterMillis)
+ ", mNotifyCurrentStatus=" + mNotifyCurrentStatus
+ + ", mVideoBitrateBps=" + mVideoBitrateBps
+ " }";
}
@@ -130,7 +138,7 @@ public final class MediaQualityThreshold implements Parcelable {
return Objects.hash(Arrays.hashCode(mRtpInactivityTimerMillis), mRtcpInactivityTimerMillis,
mRtpHysteresisTimeInMillis, mRtpPacketLossDurationMillis,
Arrays.hashCode(mRtpPacketLossRate), Arrays.hashCode(mRtpJitterMillis),
- mNotifyCurrentStatus);
+ mNotifyCurrentStatus, mVideoBitrateBps);
}
@Override
@@ -151,7 +159,8 @@ public final class MediaQualityThreshold implements Parcelable {
&& mRtpPacketLossDurationMillis == s.mRtpPacketLossDurationMillis
&& Arrays.equals(mRtpPacketLossRate, s.mRtpPacketLossRate)
&& Arrays.equals(mRtpJitterMillis, s.mRtpJitterMillis)
- && mNotifyCurrentStatus == s.mNotifyCurrentStatus);
+ && mNotifyCurrentStatus == s.mNotifyCurrentStatus
+ && mVideoBitrateBps == s.mVideoBitrateBps);
}
/**
@@ -172,6 +181,7 @@ public final class MediaQualityThreshold implements Parcelable {
dest.writeIntArray(mRtpPacketLossRate);
dest.writeIntArray(mRtpJitterMillis);
dest.writeBoolean(mNotifyCurrentStatus);
+ dest.writeInt(mVideoBitrateBps);
}
public static final @NonNull Parcelable.Creator<MediaQualityThreshold>
@@ -198,6 +208,7 @@ public final class MediaQualityThreshold implements Parcelable {
private int[] mRtpPacketLossRate;
private int[] mRtpJitterMillis;
private boolean mNotifyCurrentStatus;
+ private int mVideoBitrateBps;
/**
* Default constructor for Builder.
@@ -209,6 +220,7 @@ public final class MediaQualityThreshold implements Parcelable {
mRtpPacketLossDurationMillis = 0;
mRtpPacketLossRate = new int[0];
mRtpJitterMillis = new int[0];
+ mVideoBitrateBps = 0;
}
/**
@@ -303,6 +315,16 @@ public final class MediaQualityThreshold implements Parcelable {
}
/**
+ * The receiving bitrate threshold in bps for video call. If it is not zero, bitrate
+ * notification event is triggered when the receiving frame bitrate is less than the
+ * threshold.
+ */
+ public @NonNull Builder setVideoBitrateBps(final int bitrate) {
+ this.mVideoBitrateBps = bitrate;
+ return this;
+ }
+
+ /**
* Build the MediaQualityThreshold.
*
* @return the MediaQualityThreshold object.
diff --git a/framework/src/android/telephony/imsmedia/VideoSessionCallback.java b/framework/src/android/telephony/imsmedia/VideoSessionCallback.java
index cf66ee56..17748bbb 100644
--- a/framework/src/android/telephony/imsmedia/VideoSessionCallback.java
+++ b/framework/src/android/telephony/imsmedia/VideoSessionCallback.java
@@ -151,12 +151,12 @@ public class VideoSessionCallback extends ImsMediaManager.SessionCallback {
}
@Override
- public void notifyPacketLoss(final int packetLossPercentage) {
+ public void notifyBitrate(final int bitrate) {
if (mLocalCallback == null) return;
final long callingIdentity = Binder.clearCallingIdentity();
try {
- mExecutor.execute(() -> mLocalCallback.notifyPacketLoss(packetLossPercentage));
+ mExecutor.execute(() -> mLocalCallback.notifyBitrate(bitrate));
} finally {
restoreCallingIdentity(callingIdentity);
}
@@ -234,13 +234,12 @@ public class VideoSessionCallback extends ImsMediaManager.SessionCallback {
}
/**
- * Notifies RTP packet loss observed as per thresholds set by
+ * Notifies when the video bitrate decreased below the threshold set by
* setMediaQualityThreshold() API
*
- * @param packetLossPercentage percentage of packet loss calculated
- * over the duration
+ * @param bitrate The bitrate of sending video packets in bps unit
*/
- public void notifyPacketLoss(final int packetLossPercentage) {
+ public void notifyBitrate(final int bitrate) {
// Base Implementation
}
diff --git a/service/src/com/android/telephony/imsmedia/Utils.java b/service/src/com/android/telephony/imsmedia/Utils.java
index 651413b5..5459e6c8 100644
--- a/service/src/com/android/telephony/imsmedia/Utils.java
+++ b/service/src/com/android/telephony/imsmedia/Utils.java
@@ -392,6 +392,7 @@ public final class Utils {
.setRtpPacketLossRate(in.rtpPacketLossRate)
.setRtpJitterMillis(in.rtpJitterMillis)
.setNotifyCurrentStatus(in.notifyCurrentStatus)
+ .setVideoBitrateBps(0)
.build();
}
diff --git a/service/src/com/android/telephony/imsmedia/VideoListener.java b/service/src/com/android/telephony/imsmedia/VideoListener.java
index ce70114b..32122974 100644
--- a/service/src/com/android/telephony/imsmedia/VideoListener.java
+++ b/service/src/com/android/telephony/imsmedia/VideoListener.java
@@ -92,7 +92,7 @@ public class VideoListener implements JNIImsMediaListener {
//TODO: add implementation
break;
case VideoSession.EVENT_MEDIA_INACTIVITY_IND:
- case VideoSession.EVENT_PACKET_LOSS_IND:
+ case VideoSession.EVENT_NOTIFY_BITRATE_IND:
Utils.sendMessage(mHandler, event, parcel.readInt(), Utils.UNUSED);
break;
case VideoSession.EVENT_VIDEO_DATA_USAGE_IND:
diff --git a/service/src/com/android/telephony/imsmedia/VideoSession.java b/service/src/com/android/telephony/imsmedia/VideoSession.java
index 5ade826e..02d47ad9 100644
--- a/service/src/com/android/telephony/imsmedia/VideoSession.java
+++ b/service/src/com/android/telephony/imsmedia/VideoSession.java
@@ -59,7 +59,7 @@ public final class VideoSession extends IImsVideoSession.Stub implements IMediaS
public static final int EVENT_PEER_DIMENSION_CHANGED = 205;
public static final int EVENT_RTP_HEADER_EXTENSION_IND = 206;
public static final int EVENT_MEDIA_INACTIVITY_IND = 207;
- public static final int EVENT_PACKET_LOSS_IND = 208;
+ public static final int EVENT_NOTIFY_BITRATE_IND = 208;
public static final int EVENT_VIDEO_DATA_USAGE_IND = 209;
public static final int EVENT_SESSION_CLOSED = 210;
@@ -233,8 +233,8 @@ public final class VideoSession extends IImsVideoSession.Stub implements IMediaS
case EVENT_MEDIA_INACTIVITY_IND:
handleNotifyMediaInactivityInd(msg.arg1);
break;
- case EVENT_PACKET_LOSS_IND:
- handleNotifyPacketLossInd(msg.arg1);
+ case EVENT_NOTIFY_BITRATE_IND:
+ handleNotifyBitrateInd(msg.arg1);
break;
case EVENT_VIDEO_DATA_USAGE_IND:
handleNotifyVideoDataUsage((long) msg.obj);
@@ -344,9 +344,9 @@ public final class VideoSession extends IImsVideoSession.Stub implements IMediaS
}
}
- private void handleNotifyPacketLossInd(int percentage) {
+ private void handleNotifyBitrateInd(int percentage) {
try {
- mCallback.notifyPacketLoss(percentage);
+ mCallback.notifyBitrate(percentage);
} catch (RemoteException e) {
Log.e(TAG, "Failed to notify packet loss: " + e);
}
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/include/MediaQualityThreshold.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/include/MediaQualityThreshold.h
index ecb33980..d7b7ced3 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/include/MediaQualityThreshold.h
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/include/MediaQualityThreshold.h
@@ -58,6 +58,8 @@ public:
std::vector<int32_t> getRtpJitterMillis() const;
void setNotifyCurrentStatus(bool status);
bool getNotifyCurrentStatus() const;
+ void setVideoBitrateBps(int32_t bitrate);
+ int32_t getVideoBitrateBps() const;
private:
/** The timer in milliseconds for monitoring RTP inactivity */
@@ -85,6 +87,13 @@ private:
* of the current status.
*/
bool mNotifyCurrentStatus;
+
+ /**
+ * The receiving bitrate threshold in bps for video call. If it is not zero, bitrate
+ * notification event is triggered when the receiving frame bitrate is less than the
+ * threshold.
+ */
+ int mVideoBitrateBps;
};
} // namespace imsmedia
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/src/MediaQualityThreshold.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/src/MediaQualityThreshold.cpp
index f0ca1473..c6ecefdd 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/src/MediaQualityThreshold.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/src/MediaQualityThreshold.cpp
@@ -34,6 +34,7 @@ MediaQualityThreshold::MediaQualityThreshold()
mRtpPacketLossRate.clear();
mRtpJitterMillis.clear();
mNotifyCurrentStatus = false;
+ mVideoBitrateBps = 0;
}
MediaQualityThreshold::MediaQualityThreshold(const MediaQualityThreshold& threshold)
@@ -45,6 +46,7 @@ MediaQualityThreshold::MediaQualityThreshold(const MediaQualityThreshold& thresh
mRtpPacketLossRate = threshold.mRtpPacketLossRate;
mRtpJitterMillis = threshold.mRtpJitterMillis;
mNotifyCurrentStatus = threshold.mNotifyCurrentStatus;
+ mVideoBitrateBps = threshold.mVideoBitrateBps;
}
MediaQualityThreshold::~MediaQualityThreshold() {}
@@ -60,6 +62,7 @@ MediaQualityThreshold& MediaQualityThreshold::operator=(const MediaQualityThresh
mRtpPacketLossRate = threshold.mRtpPacketLossRate;
mRtpJitterMillis = threshold.mRtpJitterMillis;
mNotifyCurrentStatus = threshold.mNotifyCurrentStatus;
+ mVideoBitrateBps = threshold.mVideoBitrateBps;
}
return *this;
}
@@ -72,7 +75,8 @@ bool MediaQualityThreshold::operator==(const MediaQualityThreshold& threshold) c
mRtpPacketLossDurationMillis == threshold.mRtpPacketLossDurationMillis &&
mRtpPacketLossRate == threshold.mRtpPacketLossRate &&
mRtpJitterMillis == threshold.mRtpJitterMillis &&
- mNotifyCurrentStatus == threshold.mNotifyCurrentStatus);
+ mNotifyCurrentStatus == threshold.mNotifyCurrentStatus &&
+ mVideoBitrateBps == threshold.mVideoBitrateBps);
}
bool MediaQualityThreshold::operator!=(const MediaQualityThreshold& threshold) const
@@ -83,7 +87,8 @@ bool MediaQualityThreshold::operator!=(const MediaQualityThreshold& threshold) c
mRtpPacketLossDurationMillis != threshold.mRtpPacketLossDurationMillis ||
mRtpPacketLossRate != threshold.mRtpPacketLossRate ||
mRtpJitterMillis != threshold.mRtpJitterMillis ||
- mNotifyCurrentStatus != threshold.mNotifyCurrentStatus);
+ mNotifyCurrentStatus != threshold.mNotifyCurrentStatus ||
+ mVideoBitrateBps != threshold.mVideoBitrateBps);
}
status_t MediaQualityThreshold::writeToParcel(Parcel* out) const
@@ -113,6 +118,7 @@ status_t MediaQualityThreshold::writeToParcel(Parcel* out) const
}
out->writeInt32(mNotifyCurrentStatus ? 1 : 0);
+ out->writeInt32(mVideoBitrateBps);
return NO_ERROR;
}
@@ -149,7 +155,7 @@ status_t MediaQualityThreshold::readFromParcel(const Parcel* in)
int32_t value;
in->readInt32(&value);
value == 1 ? mNotifyCurrentStatus = true : mNotifyCurrentStatus = false;
-
+ in->readInt32(&mVideoBitrateBps);
return NO_ERROR;
}
@@ -223,6 +229,16 @@ bool MediaQualityThreshold::getNotifyCurrentStatus() const
return mNotifyCurrentStatus;
}
+void MediaQualityThreshold::setVideoBitrateBps(int32_t bitrate)
+{
+ mVideoBitrateBps = bitrate;
+}
+
+int32_t MediaQualityThreshold::getVideoBitrateBps() const
+{
+ return mVideoBitrateBps;
+}
+
} // namespace imsmedia
} // namespace telephony
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/ImsMediaDefine.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/ImsMediaDefine.h
index 891513dd..75d70238 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/ImsMediaDefine.h
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/ImsMediaDefine.h
@@ -52,6 +52,7 @@ enum kImsMediaEventType
kImsMediaEventResolutionChanged,
kImsMediaEventNotifyVideoDataUsage,
kImsMediaEventNotifyRttReceived,
+ kImsMediaEventNotifyVideoLowestBitrate,
};
// Internal Request Event
@@ -331,7 +332,7 @@ enum ImsMediaVideoMsgResponse
kVideoPeerDimensionChanged,
kVideoRtpHeaderExtensionInd,
kVideoMediaInactivityInd,
- kVideoPacketLossInd,
+ kVideoBitrateInd,
kVideoDataUsageInd,
kVideoSessionClosed,
};
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/VideoStreamGraphRtpTx.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/VideoStreamGraphRtpTx.h
index 1255d194..0fd1104a 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/VideoStreamGraphRtpTx.h
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/VideoStreamGraphRtpTx.h
@@ -29,6 +29,7 @@ public:
virtual ImsMediaResult create(RtpConfig* config);
virtual ImsMediaResult update(RtpConfig* config);
virtual ImsMediaResult start();
+ virtual bool setMediaQualityThreshold(MediaQualityThreshold* threshold);
void setSurface(ANativeWindow* surface);
virtual bool OnEvent(int32_t type, uint64_t param1, uint64_t param2);
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaVideoSource.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaVideoSource.h
index 83a6d7ac..b1adce53 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaVideoSource.h
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaVideoSource.h
@@ -137,7 +137,7 @@ public:
*
* @param bitrate The bitrate in bps units
*/
- void changeBitrate(const uint32_t bitrate);
+ bool changeBitrate(const uint32_t bitrate);
/**
* @brief Request a new IDR frame to the codec output streaming
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/nodes/IVideoSourceNode.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/nodes/IVideoSourceNode.h
index bcc43d5b..17acd172 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/nodes/IVideoSourceNode.h
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/nodes/IVideoSourceNode.h
@@ -46,6 +46,14 @@ public:
* @param window surface buffer to update
*/
void UpdateSurface(ANativeWindow* window);
+
+ /**
+ * @brief Set the bitrate threshold to notify the indication when the encoding video bitrate is
+ * less than the threshold values
+ *
+ * @param bitrate The video encoding bitrate in bps unit
+ */
+ void SetBitrateThreshold(int32_t bitrate);
// callback from ImsMediaVideoSource
virtual void OnUplinkEvent(uint8_t* pBitstream, uint32_t nSize, int64_t pstUsec, uint32_t flag);
virtual void OnEvent(int32_t type, int32_t param1, int32_t param2);
@@ -68,6 +76,8 @@ protected:
android::String8 mImagePath;
uint32_t mDeviceOrientation;
ANativeWindow* mWindow;
+ int32_t mMinBitrateThreshold;
+ bool mBitrateNotified;
};
#endif \ No newline at end of file
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoManager.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoManager.cpp
index 9d98be37..a52db04a 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoManager.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoManager.cpp
@@ -407,12 +407,7 @@ void VideoManager::ResponseHandler::processEvent(
// TODO : add implementation
break;
case kVideoMediaInactivityInd:
- parcel.writeInt32(event);
- parcel.writeInt32(static_cast<int>(paramA)); // type
- parcel.writeInt32(static_cast<int>(paramB)); // duration
- VideoManager::getInstance()->sendResponse(sessionId, parcel);
- break;
- case kVideoPacketLossInd:
+ case kVideoBitrateInd:
parcel.writeInt32(event);
parcel.writeInt32(static_cast<int>(paramA));
VideoManager::getInstance()->sendResponse(sessionId, parcel);
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoSession.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoSession.cpp
index 074e37cf..ba43d0a0 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoSession.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoSession.cpp
@@ -106,6 +106,7 @@ ImsMediaResult VideoSession::startGraph(RtpConfig* config)
if (mGraphRtpTx != nullptr)
{
+ mGraphRtpTx->setMediaQualityThreshold(&mThreshold);
ret = mGraphRtpTx->update(config);
if (ret != RESULT_SUCCESS)
@@ -135,6 +136,7 @@ ImsMediaResult VideoSession::startGraph(RtpConfig* config)
if (pConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_ONLY ||
pConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE)
{
+ mGraphRtpTx->setMediaQualityThreshold(&mThreshold);
ret = mGraphRtpTx->start();
}
}
@@ -265,6 +267,10 @@ void VideoSession::onEvent(int32_t type, uint64_t param1, uint64_t param2)
ImsMediaEventHandler::SendEvent(
"VIDEO_RESPONSE_EVENT", kVideoDataUsageInd, mSessionId, param1, param2);
break;
+ case kImsMediaEventNotifyVideoLowestBitrate:
+ ImsMediaEventHandler::SendEvent(
+ "VIDEO_RESPONSE_EVENT", kVideoBitrateInd, mSessionId, param1, param2);
+ break;
case kRequestVideoCvoUpdate:
case kRequestVideoBitrateChange:
case kRequestVideoIdrFrame:
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTx.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTx.cpp
index 71a6f050..bc7c7dd0 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTx.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTx.cpp
@@ -234,6 +234,23 @@ ImsMediaResult VideoStreamGraphRtpTx::start()
return RESULT_SUCCESS;
}
+bool VideoStreamGraphRtpTx::setMediaQualityThreshold(MediaQualityThreshold* threshold)
+{
+ if (threshold != nullptr)
+ {
+ BaseNode* node = findNode(kNodeIdVideoSource);
+
+ if (node != nullptr)
+ {
+ IVideoSourceNode* source = reinterpret_cast<IVideoSourceNode*>(node);
+ source->SetBitrateThreshold(threshold->getVideoBitrateBps());
+ return true;
+ }
+ }
+
+ return false;
+}
+
void VideoStreamGraphRtpTx::setSurface(ANativeWindow* surface)
{
IMLOGI1("[setSurface] state[%d]", mGraphState);
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp
index 591b6d05..38b71771 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp
@@ -448,14 +448,14 @@ void ImsMediaVideoSource::onCameraFrame(AImage* pImage)
processOutputBuffer();
}
-void ImsMediaVideoSource::changeBitrate(const uint32_t bitrate)
+bool ImsMediaVideoSource::changeBitrate(const uint32_t bitrate)
{
IMLOGD1("[changeBitrate] bitrate[%d]", bitrate);
std::lock_guard<std::mutex> guard(mMutex);
if (mStopped)
{
- return;
+ return false;
}
AMediaFormat* params = AMediaFormat_new();
@@ -465,7 +465,10 @@ void ImsMediaVideoSource::changeBitrate(const uint32_t bitrate)
if (status != AMEDIA_OK)
{
IMLOGE1("[changeBitrate] error[%d]", status);
+ return false;
}
+
+ return true;
}
void ImsMediaVideoSource::requestIdrFrame()
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/IVideoSourceNode.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/IVideoSourceNode.cpp
index a54dc377..c95f6240 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/IVideoSourceNode.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/IVideoSourceNode.cpp
@@ -45,6 +45,8 @@ IVideoSourceNode::IVideoSourceNode(BaseSessionCallback* callback) :
mImagePath = "";
mDeviceOrientation = 0;
mWindow = nullptr;
+ mMinBitrateThreshold = 0;
+ mBitrateNotified = false;
}
IVideoSourceNode::~IVideoSourceNode() {}
@@ -83,12 +85,13 @@ ImsMediaResult IVideoSourceNode::Start()
mVideoSource->SetSurface(mWindow);
- if (mVideoSource->Start() == false)
+ if (!mVideoSource->Start())
{
return RESULT_NOT_READY;
}
mVideoSource->SetDeviceOrientation(mDeviceOrientation);
+ mBitrateNotified = false;
}
mNodeState = kNodeStateRunning;
@@ -275,6 +278,12 @@ void IVideoSourceNode::OnUplinkEvent(
}
}
+void IVideoSourceNode::SetBitrateThreshold(int32_t bitrate)
+{
+ IMLOGD1("[SetBitrateThreshold] bitrate[%d]", bitrate);
+ mMinBitrateThreshold = bitrate;
+}
+
void IVideoSourceNode::OnEvent(int32_t type, int32_t param1, int32_t param2)
{
IMLOGD3("[OnEvent] type[%d], param1[%d], param2[%d]", type, param1, param2);
@@ -296,7 +305,15 @@ void IVideoSourceNode::OnEvent(int32_t type, int32_t param1, int32_t param2)
case kRequestVideoBitrateChange:
if (mVideoSource != nullptr)
{
- mVideoSource->changeBitrate(param1);
+ if (mVideoSource->changeBitrate(param1))
+ {
+ if (mMinBitrateThreshold != 0 && param1 <= mMinBitrateThreshold &&
+ mCallback != nullptr && !mBitrateNotified)
+ {
+ mCallback->SendEvent(kImsMediaEventNotifyVideoLowestBitrate, param1);
+ mBitrateNotified = true;
+ }
+ }
}
break;
case kRequestVideoIdrFrame:
diff --git a/test/app/ImsMediaTestingApp/app/src/main/java/com/example/imsmediatestingapp/MainActivity.java b/test/app/ImsMediaTestingApp/app/src/main/java/com/example/imsmediatestingapp/MainActivity.java
index 51e981fa..f31d68b3 100644
--- a/test/app/ImsMediaTestingApp/app/src/main/java/com/example/imsmediatestingapp/MainActivity.java
+++ b/test/app/ImsMediaTestingApp/app/src/main/java/com/example/imsmediatestingapp/MainActivity.java
@@ -119,6 +119,7 @@ public class MainActivity extends AppCompatActivity {
private static final int[] PACKET_LOSS_RATE = { 1, 3 };
private static final int[] JITTER_THRESHOLD = { 100, 200 };
private static final boolean NOTIFY_STATUS = false;
+ private static final int VIDEO_BITRATE_THRESHOLD_BPS = 100000;
private Set<Integer> mSelectedCodecTypes = new HashSet<>();
private Set<Integer> mSelectedAmrModes = new HashSet<>();
@@ -819,6 +820,28 @@ public class MainActivity extends AppCompatActivity {
mVideoSession = (ImsVideoSession) session;
Log.d(TAG, "onOpenSessionSuccess: id=" + mVideoSession.getSessionId());
mIsVideoSessionOpened = true;
+
+ MediaQualityThreshold threshold = createMediaQualityThreshold(RTP_TIMEOUT,
+ RTCP_TIMEOUT, RTP_HYSTERESIS_TIME, RTP_PACKET_LOSS_DURATION, PACKET_LOSS_RATE,
+ JITTER_THRESHOLD, NOTIFY_STATUS);
+ mVideoSession.setMediaQualityThreshold(threshold);
+
+ int rtcpfbTypes = 0;
+ for (int types : mSelectedRtcpFbTypes) {
+ rtcpfbTypes |= types;
+ }
+
+ mVideoConfig = createVideoConfig(mSelectedVideoCodec, mSelectedVideoMode,
+ mSelectedFramerate, mSelectedBitrate, mSelectedCodecProfile,
+ mSelectedCodecLevel, mSelectedCameraId, mSelectedCameraZoom,
+ mSelectedDeviceOrientationDegree,
+ mSelectedCvoValue, rtcpfbTypes,
+ getResolutionWidth(mSelectedVideoResolution),
+ getResolutionHeight(mSelectedVideoResolution));
+
+ Log.d(TAG, "VideoConfig: " + mVideoConfig.toString());
+ mVideoSession.modifySession(mVideoConfig);
+
runOnUiThread(() -> {
if (mIsPreviewSurfaceSet) {
mVideoSession.setPreviewSurface(mPreviewSurface);
@@ -828,6 +851,22 @@ public class MainActivity extends AppCompatActivity {
}
});
}
+
+ @Override
+ public void onModifySessionResponse(VideoConfig config,
+ final @ImsMediaSession.SessionOperationResult int result) {
+ Log.d(TAG, "onModifySessionResponse");
+ }
+
+ @Override
+ public void onPeerDimensionChanged(final int width, final int height) {
+ Log.d(TAG, "onPeerDimensionChanged - width=" + width + ", height=" + height);
+ }
+
+ @Override
+ public void notifyBitrate(final int bitrate) {
+ Log.d(TAG, "notifyBitrate - bitrate=" + bitrate);
+ }
}
private class RtpTextSessionCallback extends TextSessionCallback {
@@ -1517,6 +1556,7 @@ public class MainActivity extends AppCompatActivity {
.setRtpPacketLossRate(rtpPacketLossRate)
.setRtpJitterMillis(rtpJitterMillis)
.setNotifyCurrentStatus(notifyCurrentStatus)
+ .setVideoBitrateBps(VIDEO_BITRATE_THRESHOLD_BPS)
.build();
}
@@ -1857,11 +1897,6 @@ public class MainActivity extends AppCompatActivity {
mAudioConfig = determineAudioConfig(mLocalDeviceInfo, mRemoteDeviceInfo);
Log.d(TAG, "AudioConfig: " + mAudioConfig.toString());
- int rtcpfbTypes = 0;
- for (int types : mSelectedRtcpFbTypes) {
- rtcpfbTypes |= types;
- }
-
RtpAudioSessionCallback sessionAudioCallback = new RtpAudioSessionCallback();
mImsMediaManager.openSession(mAudioRtp, mAudioRtcp,
ImsMediaSession.SESSION_TYPE_AUDIO,
@@ -1870,19 +1905,10 @@ public class MainActivity extends AppCompatActivity {
+ mRemoteDeviceInfo.getAudioRtpPort());
if (mVideoEnabled) {
- mVideoConfig = createVideoConfig(mSelectedVideoCodec, mSelectedVideoMode,
- mSelectedFramerate, mSelectedBitrate, mSelectedCodecProfile,
- mSelectedCodecLevel, mSelectedCameraId, mSelectedCameraZoom,
- mSelectedDeviceOrientationDegree,
- mSelectedCvoValue, rtcpfbTypes,
- getResolutionWidth(mSelectedVideoResolution),
- getResolutionHeight(mSelectedVideoResolution));
- Log.d(TAG, "VideoConfig: " + mVideoConfig.toString());
-
RtpVideoSessionCallback sessionVideoCallback = new RtpVideoSessionCallback();
mImsMediaManager.openSession(mVideoRtp, mVideoRtcp,
ImsMediaSession.SESSION_TYPE_VIDEO,
- mVideoConfig, mExecutor, sessionVideoCallback);
+ null, mExecutor, sessionVideoCallback);
Log.d(TAG, "openSession(): video=" + mRemoteDeviceInfo.getInetAddress() + ":"
+ mRemoteDeviceInfo.getVideoRtpPort());
}
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityThresholdTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityThresholdTest.cpp
index 1ab1ff01..33494468 100644
--- a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityThresholdTest.cpp
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityThresholdTest.cpp
@@ -26,6 +26,7 @@ const int32_t kRtpPacketLossDurationMillis = 5000;
const std::vector<int32_t> kRtpPacketLossRate = {3, 5};
const std::vector<int32_t> kRtpJitterMillis = {100, 200};
const bool kNotifyCurrentStatus = false;
+const int32_t kVideoBitrateBps = 100000;
class MediaQualityThresholdTest : public ::testing::Test
{
@@ -42,6 +43,7 @@ protected:
threshold.setRtpPacketLossRate(kRtpPacketLossRate);
threshold.setRtpJitterMillis(kRtpJitterMillis);
threshold.setNotifyCurrentStatus(kNotifyCurrentStatus);
+ threshold.setVideoBitrateBps(kVideoBitrateBps);
}
virtual void TearDown() override {}
@@ -56,6 +58,7 @@ TEST_F(MediaQualityThresholdTest, TestGetterSetter)
EXPECT_EQ(threshold.getRtpPacketLossRate(), kRtpPacketLossRate);
EXPECT_EQ(threshold.getRtpJitterMillis(), kRtpJitterMillis);
EXPECT_EQ(threshold.getNotifyCurrentStatus(), kNotifyCurrentStatus);
+ EXPECT_EQ(threshold.getVideoBitrateBps(), kVideoBitrateBps);
}
TEST_F(MediaQualityThresholdTest, TestParcel)
@@ -85,6 +88,7 @@ TEST_F(MediaQualityThresholdTest, TestEqual)
threshold2.setRtpPacketLossRate(kRtpPacketLossRate);
threshold2.setRtpJitterMillis(kRtpJitterMillis);
threshold2.setNotifyCurrentStatus(kNotifyCurrentStatus);
+ threshold2.setVideoBitrateBps(kVideoBitrateBps);
EXPECT_EQ(threshold, threshold2);
}
@@ -98,6 +102,7 @@ TEST_F(MediaQualityThresholdTest, TestNotEqual)
threshold2.setRtpPacketLossRate(kRtpPacketLossRate);
threshold2.setRtpJitterMillis(kRtpJitterMillis);
threshold2.setNotifyCurrentStatus(kNotifyCurrentStatus);
+ threshold2.setVideoBitrateBps(kVideoBitrateBps);
MediaQualityThreshold threshold3;
threshold3.setRtpInactivityTimerMillis(kRtpInactivityTimerMillis);
@@ -107,6 +112,7 @@ TEST_F(MediaQualityThresholdTest, TestNotEqual)
threshold3.setRtpPacketLossRate(std::vector<int32_t>{5, 10});
threshold3.setRtpJitterMillis(kRtpJitterMillis);
threshold3.setNotifyCurrentStatus(kNotifyCurrentStatus);
+ threshold3.setVideoBitrateBps(kVideoBitrateBps);
EXPECT_NE(threshold, threshold2);
EXPECT_NE(threshold, threshold3);
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTxTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTxTest.cpp
index 332041c4..20f368ba 100644
--- a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTxTest.cpp
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTxTest.cpp
@@ -123,6 +123,12 @@ protected:
1, &previewReader),
AMEDIA_OK);
AImageReader_getWindow(previewReader, &previewSurface);
+
+ /*
+ * TODO: Below line will skip all test under this class, need to remove to include it in
+ * atest
+ */
+ GTEST_SKIP();
}
virtual void TearDown() override
diff --git a/tests/unit/src/com/android/telephony/imsmedia/AudioOffloadTest.java b/tests/unit/src/com/android/telephony/imsmedia/AudioOffloadTest.java
index 23ec9b0d..c3013544 100644
--- a/tests/unit/src/com/android/telephony/imsmedia/AudioOffloadTest.java
+++ b/tests/unit/src/com/android/telephony/imsmedia/AudioOffloadTest.java
@@ -259,7 +259,8 @@ public class AudioOffloadTest extends ImsMediaTest {
@Test
public void testSetMediaQualityThreshold() {
// Set Media Quality Threshold
- MediaQualityThreshold threshold = MediaQualityThresholdTest.createMediaQualityThreshold();
+ MediaQualityThreshold threshold =
+ MediaQualityThresholdTest.createMediaQualityThresholdForHal();
audioSession.setMediaQualityThreshold(threshold);
processAllMessages();
try {
diff --git a/tests/unit/src/com/android/telephony/imsmedia/MediaQualityThresholdTest.java b/tests/unit/src/com/android/telephony/imsmedia/MediaQualityThresholdTest.java
index 40dfe866..d61e0f33 100644
--- a/tests/unit/src/com/android/telephony/imsmedia/MediaQualityThresholdTest.java
+++ b/tests/unit/src/com/android/telephony/imsmedia/MediaQualityThresholdTest.java
@@ -37,6 +37,7 @@ public class MediaQualityThresholdTest {
private static final int[] PACKET_LOSS_RATE = { 1, 3 };
private static final int[] JITTER_THRESHOLD = { 100, 200 };
private static final boolean NOTIFY_STATUS = false;
+ private static final int VIDEO_BITRATE_BPS = 100000;
@Test
public void testConstructorAndGetters() {
@@ -48,6 +49,7 @@ public class MediaQualityThresholdTest {
assertThat(Arrays.equals(threshold.getRtpPacketLossRate(), PACKET_LOSS_RATE)).isTrue();
assertThat(Arrays.equals(threshold.getRtpJitterMillis(), JITTER_THRESHOLD)).isTrue();
assertThat(threshold.getNotifyCurrentStatus()).isEqualTo(NOTIFY_STATUS);
+ assertThat(threshold.getVideoBitrateBps()).isEqualTo(VIDEO_BITRATE_BPS);
}
@Test
@@ -82,6 +84,7 @@ public class MediaQualityThresholdTest {
.setRtpPacketLossRate(PACKET_LOSS_RATE)
.setRtpJitterMillis(JITTER_THRESHOLD)
.setNotifyCurrentStatus(NOTIFY_STATUS)
+ .setVideoBitrateBps(VIDEO_BITRATE_BPS)
.build();
assertThat(threshold1).isNotEqualTo(threshold2);
@@ -94,6 +97,7 @@ public class MediaQualityThresholdTest {
.setRtpPacketLossRate(PACKET_LOSS_RATE)
.setRtpJitterMillis(JITTER_THRESHOLD)
.setNotifyCurrentStatus(NOTIFY_STATUS)
+ .setVideoBitrateBps(VIDEO_BITRATE_BPS)
.build();
assertThat(threshold1).isNotEqualTo(threshold3);
@@ -106,6 +110,7 @@ public class MediaQualityThresholdTest {
.setRtpPacketLossRate(PACKET_LOSS_RATE)
.setRtpJitterMillis(JITTER_THRESHOLD)
.setNotifyCurrentStatus(NOTIFY_STATUS)
+ .setVideoBitrateBps(VIDEO_BITRATE_BPS)
.build();
assertThat(threshold1).isNotEqualTo(threshold4);
@@ -119,6 +124,7 @@ public class MediaQualityThresholdTest {
.setRtpPacketLossRate(PACKET_LOSS_RATE)
.setRtpJitterMillis(JITTER_THRESHOLD)
.setNotifyCurrentStatus(NOTIFY_STATUS)
+ .setVideoBitrateBps(VIDEO_BITRATE_BPS)
.build();
assertThat(threshold1).isNotEqualTo(threshold5);
@@ -133,6 +139,20 @@ public class MediaQualityThresholdTest {
.setRtpPacketLossRate(PACKET_LOSS_RATE)
.setRtpJitterMillis(JITTER_THRESHOLD)
.setNotifyCurrentStatus(NOTIFY_STATUS)
+ .setVideoBitrateBps(VIDEO_BITRATE_BPS)
+ .build();
+ }
+
+ static MediaQualityThreshold createMediaQualityThresholdForHal() {
+ return new MediaQualityThreshold.Builder()
+ .setRtpInactivityTimerMillis(RTP_TIMEOUT)
+ .setRtcpInactivityTimerMillis(RTCP_TIMEOUT)
+ .setRtpHysteresisTimeInMillis(RTP_HYSTERESIS_TIME)
+ .setRtpPacketLossDurationMillis(RTP_PACKET_LOSS_DURATION)
+ .setRtpPacketLossRate(PACKET_LOSS_RATE)
+ .setRtpJitterMillis(JITTER_THRESHOLD)
+ .setNotifyCurrentStatus(NOTIFY_STATUS)
+ .setVideoBitrateBps(0)
.build();
}
}
diff --git a/tests/unit/src/com/android/telephony/imsmedia/VideoListenerTest.java b/tests/unit/src/com/android/telephony/imsmedia/VideoListenerTest.java
index a9948d22..d00ccb1b 100644
--- a/tests/unit/src/com/android/telephony/imsmedia/VideoListenerTest.java
+++ b/tests/unit/src/com/android/telephony/imsmedia/VideoListenerTest.java
@@ -165,14 +165,14 @@ public class VideoListenerTest extends ImsMediaTest {
}
@Test
- public void testEventPacketLossInd() throws RemoteException {
- Parcel parcel = createParcel(VideoSession.EVENT_PACKET_LOSS_IND,
+ public void testEventNotifyBitrateInd() throws RemoteException {
+ Parcel parcel = createParcel(VideoSession.EVENT_NOTIFY_BITRATE_IND,
ImsMediaSession.PACKET_TYPE_RTCP);
mVideoListener.onMessage(parcel);
processAllMessages();
parcel.recycle();
verify(mMockIImsVideoSessionCallback,
- times(1)).notifyPacketLoss(eq(ImsMediaSession.PACKET_TYPE_RTCP));
+ times(1)).notifyBitrate(eq(ImsMediaSession.PACKET_TYPE_RTCP));
}
@Test
diff --git a/tests/unit/src/com/android/telephony/imsmedia/VideoSessionTest.java b/tests/unit/src/com/android/telephony/imsmedia/VideoSessionTest.java
index 600f9778..d9e4b897 100644
--- a/tests/unit/src/com/android/telephony/imsmedia/VideoSessionTest.java
+++ b/tests/unit/src/com/android/telephony/imsmedia/VideoSessionTest.java
@@ -285,12 +285,12 @@ public class VideoSessionTest extends ImsMediaTest {
@Test
public void testPacketLossInd() {
// Receive Packet Loss
- Utils.sendMessage(mHandler, VideoSession.EVENT_PACKET_LOSS_IND, PACKET_LOSS, UNUSED);
+ Utils.sendMessage(mHandler, VideoSession.EVENT_NOTIFY_BITRATE_IND, PACKET_LOSS, UNUSED);
processAllMessages();
try {
- verify(mCallback, times(1)).notifyPacketLoss(eq(PACKET_LOSS));
+ verify(mCallback, times(1)).notifyBitrate(eq(PACKET_LOSS));
} catch (RemoteException e) {
- fail("Failed to notify notifyPacketLoss: " + e);
+ fail("Failed to notify notifyBitrate: " + e);
}
}