Skip to content
This repository has been archived by the owner on Apr 12, 2022. It is now read-only.

Commit

Permalink
Commit for VoIP Checklist #351
Browse files Browse the repository at this point in the history
Add the rear/front switch camera feature
Add new flow to display the call termination reason
  • Loading branch information
pedroGitt committed Aug 9, 2016
1 parent 75c6a0f commit 70832eb
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 75 deletions.
27 changes: 10 additions & 17 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Settings specified in this file will override any Gradle settings
# configured through the IDE.

## Project-wide Gradle settings.
#
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true


#Mon Aug 01 11:06:02 CEST 2016
systemProp.https.proxyPort=8080
systemProp.http.proxyHost=genproxy
org.gradle.daemon=true
org.gradle.parallel=true
systemProp.https.proxyHost=genproxy
org.gradle.configureondemand=true

# To do a signed release APK, put these variables in ~/.gradle/gradle.properties
# RELEASE_STORE_FILE=/path/to/keystore
# RELEASE_STORE_PASSWORD=password
# RELEASE_KEY_ALIAS=alias
# RELEASE_KEY_PASSWORD=password
org.gradle.parallel=true
systemProp.http.proxyPort=8080
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
47 changes: 46 additions & 1 deletion vector/src/main/java/im/vector/activity/CommonActivityUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import android.widget.Toast;

import org.matrix.androidsdk.MXSession;
import org.matrix.androidsdk.call.IMXCall;
import org.matrix.androidsdk.data.IMXStore;
import org.matrix.androidsdk.data.Room;
import org.matrix.androidsdk.data.RoomPreviewData;
Expand All @@ -66,7 +67,6 @@
import im.vector.contacts.PIDsRetriever;
import im.vector.fragments.AccountsSelectionDialogFragment;
import im.vector.ga.GAHelper;
import im.vector.receiver.VectorUniversalLinkReceiver;
import im.vector.services.EventStreamService;

import java.io.File;
Expand Down Expand Up @@ -1531,6 +1531,22 @@ public static String saveImageIntoGallery(Context context, File sourceFile) {
// toast utils
//==============================================================================================================

/**
* Helper method to display a toast message.
* @param aCallingActivity calling Activity instance
* @param aMsgToDisplay message to display
*/
public static void displayToastOnUiThread(final Activity aCallingActivity, final String aMsgToDisplay) {
if(null != aCallingActivity) {
aCallingActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
CommonActivityUtils.displayToast(aCallingActivity.getApplicationContext(), aMsgToDisplay);
}
});
}
}

/**
* Display a toast
* @param aContext the context.
Expand All @@ -1549,6 +1565,35 @@ public static void displaySnack(View aTargetView, CharSequence aTextToDisplay) {
Snackbar.make(aTargetView, aTextToDisplay, Snackbar.LENGTH_SHORT).show();
}

//==============================================================================================================
// call utils
//==============================================================================================================

/**
* Display a toast message according to the end call reason.
*
* @param aCallingActivity calling activity
* @param aCallEndReason define the reason of the end call
*/
public static void processEndCallInfo(Activity aCallingActivity, int aCallEndReason) {
if(null != aCallingActivity) {
if (IMXCall.END_CALL_REASON_UNDEFINED != aCallEndReason) {
switch (aCallEndReason) {
case IMXCall.END_CALL_REASON_PEER_HANG_UP:
CommonActivityUtils.displayToastOnUiThread(aCallingActivity, aCallingActivity.getString(R.string.call_error_peer_hangup));
break;

case IMXCall.END_CALL_REASON_PEER_HANG_UP_ELSEWHERE:
CommonActivityUtils.displayToastOnUiThread(aCallingActivity, aCallingActivity.getString(R.string.call_error_peer_hangup_elsewhere));
break;

default:
break;
}
}
}
}

//==============================================================================================================
// room utils
//==============================================================================================================
Expand Down
29 changes: 8 additions & 21 deletions vector/src/main/java/im/vector/activity/InComingCallActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package im.vector.activity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
Expand All @@ -29,12 +28,9 @@

import org.matrix.androidsdk.MXSession;
import org.matrix.androidsdk.call.IMXCall;
import org.matrix.androidsdk.data.Room;
import org.matrix.androidsdk.rest.model.RoomMember;

import im.vector.Matrix;
import im.vector.R;
import im.vector.VectorApp;
import im.vector.util.VectorUtils;

/**
Expand All @@ -59,27 +55,19 @@ public void onStateDidChange(String state) {
Log.d(LOG_TAG,"## onStateDidChange(): state="+state);
}

private void showToast(final String aMsgToDisplay) {
InComingCallActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
CommonActivityUtils.displayToast(InComingCallActivity.this.getApplicationContext(),aMsgToDisplay);
}
});
}

@Override
public void onCallError(String aErrorMsg) {
Log.d(LOG_TAG, "## onCallError(): error=" + aErrorMsg);
Log.d(LOG_TAG, "## dispatchOnCallError(): error=" + aErrorMsg);

if (IMXCall.CALL_ERROR_USER_NOT_RESPONDING.equals(aErrorMsg)) {
showToast(InComingCallActivity.this.getString(R.string.call_error_user_not_responding));
CommonActivityUtils.displayToastOnUiThread(InComingCallActivity.this, InComingCallActivity.this.getString(R.string.call_error_user_not_responding));
} else if (IMXCall.CALL_ERROR_ICE_FAILED.equals(aErrorMsg)) {
showToast(InComingCallActivity.this.getString(R.string.call_error_ice_failed));
CommonActivityUtils.displayToastOnUiThread(InComingCallActivity.this, InComingCallActivity.this.getString(R.string.call_error_ice_failed));
} else if (IMXCall.CALL_ERROR_CAMERA_INIT_FAILED.equals(aErrorMsg)) {
showToast(InComingCallActivity.this.getString(R.string.call_error_camera_init_failed));
CommonActivityUtils.displayToastOnUiThread(InComingCallActivity.this, InComingCallActivity.this.getString(R.string.call_error_camera_init_failed));
} else {
showToast(aErrorMsg);
CommonActivityUtils.displayToastOnUiThread(InComingCallActivity.this, aErrorMsg);
}
}

Expand Down Expand Up @@ -110,18 +98,19 @@ public void onCallAnsweredElsewhere() {
@Override
public void run() {
Log.d(LOG_TAG, "## onCallAnsweredElsewhere(): finish activity");
showToast(InComingCallActivity.this.getString(R.string.call_error_answered_elsewhere));
CommonActivityUtils.displayToastOnUiThread(InComingCallActivity.this, InComingCallActivity.this.getString(R.string.call_error_answered_elsewhere));
InComingCallActivity.this.finish();
}
});
}

@Override
public void onCallEnd() {
public void onCallEnd(final int aReasonId) {
InComingCallActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d(LOG_TAG, "## onCallEnd(): finish activity");
CommonActivityUtils.processEndCallInfo(InComingCallActivity.this, aReasonId);
InComingCallActivity.this.finish();
}
});
Expand Down Expand Up @@ -209,8 +198,6 @@ protected void onResume() {
mMxCall.onResume();
mMxCall.addListener(mMxCallListener);
}

VectorApp.setCurrentActivity(this);
}

@Override
Expand Down
63 changes: 29 additions & 34 deletions vector/src/main/java/im/vector/activity/VectorCallViewActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,16 @@ public class VectorCallViewActivity extends Activity implements SensorEventListe

// video diplay size
private IMXCall.VideoLayoutConfiguration mLocalVideoLayoutConfig;
// hard coded values are taken from specs
// hard coded values are taken from specs:
// - 585 as screen height reference
// - 18 as space between the local video and the container view containing the setting buttons
private static final float RATIO_TOP_MARGIN_LOCAL_USER_VIDEO = (float)(462.0/585.0);
private static final float VIDEO_TO_BUTTONS_VERTICAL_SPACE = (float) (18.0/585.0);
/** local user video height is set as percent of the total screen height **/
private static final int PERCENT_LOCAL_USER_VIDEO_SIZE = 25;
private static final float RATIO_LOCAL_USER_VIDEO_HEIGHT = ((float)(PERCENT_LOCAL_USER_VIDEO_SIZE))/100;
private static final float RATIO_LOCAL_USER_VIDEO_WIDTH = ((float)(PERCENT_LOCAL_USER_VIDEO_SIZE))/100;
private static final float RATIO_LOCAL_USER_VIDEO_ASPECT = 0.65f;

// sounds management
private static MediaPlayer mRingingPlayer = null;
Expand Down Expand Up @@ -228,14 +231,15 @@ public void run() {
}

@Override
public void onCallEnd() {
public void onCallEnd(final int aReasonId) {
VectorCallViewActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d(LOG_TAG, "## onCallEnd(): ");

clearCallData();
mIsCallEnded = true;
CommonActivityUtils.processEndCallInfo(VectorCallViewActivity.this, aReasonId);
VectorCallViewActivity.this.finish();
}
});
Expand Down Expand Up @@ -325,7 +329,7 @@ private void clearCallData() {

/**
* Insert the callView in the activity (above the other room member).
* The callView is setup in the SDK, and provided via onViewLoading() in {@link #mListener}.
* The callView is setup in the SDK, and provided via dispatchOnViewLoading() in {@link #mListener}.
*/
private void insertCallView() {
if(null != mCallView) {
Expand Down Expand Up @@ -401,9 +405,8 @@ public void onClick(View v) {
mSwichRearFrontCameraImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CommonActivityUtils.displayToast(VectorCallViewActivity.this.getApplicationContext(),"Not implemented");
// toggleRearFrontCamera();
// refreshSwitchRearFrontCameraButton();
toggleRearFrontCamera();
refreshSwitchRearFrontCameraButton();
}
});

Expand Down Expand Up @@ -465,7 +468,7 @@ public void onClick(View v) {
mCallView = mSavedCallview;
insertCallView();
} else {
Log.d(LOG_TAG, "onCreate: Hide the call notifications");
Log.d(LOG_TAG, "## onCreate(): Hide the call notifications");
EventStreamService.getInstance().hideCallNotifications();
mSavedCallview = null;

Expand Down Expand Up @@ -720,9 +723,9 @@ private void computeVideoUiLayout() {

// compute action bar size: the video Y component starts below the action bar
int actionBarHeight=0;
TypedValue tv = new TypedValue();
if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
TypedValue typedValue = new TypedValue();
if (getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)) {
actionBarHeight = TypedValue.complexToDimensionPixelSize(typedValue.data, getResources().getDisplayMetrics());
screenHeight -= actionBarHeight;
}

Expand All @@ -737,34 +740,24 @@ private void computeVideoUiLayout() {
float topMarginHeightNormalized = 0; // range [0;1]
float ratioVideoHeightNormalized = 0; // range [0;1]
float localVideoWidth = Math.min(screenHeight,screenWidth/*portrait is ref*/)*RATIO_LOCAL_USER_VIDEO_HEIGHT; // value effectively applied by the SDK
float estimatedLocalVideoHeight = (float) ((localVideoWidth)/(0.65)); // 0.65 => to adapt
float estimatedLocalVideoHeight = (float) ((localVideoWidth)/(RATIO_LOCAL_USER_VIDEO_ASPECT)); // 0.65 => to adapt

if(false /*Configuration.ORIENTATION_LANDSCAPE == screenOrientation*/){
Log.d(LOG_TAG,"## computeVideoUiLayout(): orientation = LANDSCAPE");

// landscape: video displayed in the left side, centered vertically
mLocalVideoLayoutConfig.mX = 0;

// for landscape, the video width is used in the Y axis
if(Configuration.ORIENTATION_LANDSCAPE == screenOrientation){
// take the video width as height
ratioVideoHeightNormalized = (localVideoWidth/screenHeight);
topMarginHeightNormalized = 1 - ratioVideoHeightNormalized - (buttonsContainerHeight/screenHeight);
topMarginHeightNormalized /=2; // centered vertically => equal space before and after the video
} else {
if(Configuration.ORIENTATION_LANDSCAPE == screenOrientation){
// take the video width as height
ratioVideoHeightNormalized = (localVideoWidth/screenHeight);
} else {
mLocalVideoLayoutConfig.mIsPortrait = true;
// take the video height as height
ratioVideoHeightNormalized = estimatedLocalVideoHeight/screenHeight;
}
Log.d(LOG_TAG,"## computeVideoUiLayout(): orientation = PORTRAIT");

// portrait: video displayed above the video buttons, centered horizontally
mLocalVideoLayoutConfig.mX = (100 - PERCENT_LOCAL_USER_VIDEO_SIZE) / 2;
topMarginHeightNormalized = 1 - ratioVideoHeightNormalized - VIDEO_TO_BUTTONS_VERTICAL_SPACE - (buttonsContainerHeight/screenHeight);
mLocalVideoLayoutConfig.mIsPortrait = true;
// take the video height as height
ratioVideoHeightNormalized = estimatedLocalVideoHeight/screenHeight;
}
Log.d(LOG_TAG,"## computeVideoUiLayout(): orientation = PORTRAIT");

// the video is displayed:
// - X axis: centered horizontally
mLocalVideoLayoutConfig.mX = (100 - PERCENT_LOCAL_USER_VIDEO_SIZE) / 2;

// - Y axis: above the video buttons
topMarginHeightNormalized = 1 - ratioVideoHeightNormalized - VIDEO_TO_BUTTONS_VERTICAL_SPACE - (buttonsContainerHeight/screenHeight);
if(topMarginHeightNormalized >= 0) {
mLocalVideoLayoutConfig.mY = (int) (topMarginHeightNormalized * 100);
}
Expand Down Expand Up @@ -854,9 +847,11 @@ private void refreshMuteVideoButton() {

/**
* Update the switch camera icon.
* Note that, this icon is only active if the device supports
* camera switching (See {@link IMXCall#isSwitchCameraSupported()})
*/
private void refreshSwitchRearFrontCameraButton() {
if ((null != mCall) && mCall.getCallState().equals(IMXCall.CALL_STATE_CONNECTED) && mCall.isVideo()) {
if ((null != mCall) && mCall.getCallState().equals(IMXCall.CALL_STATE_CONNECTED) && mCall.isVideo() && mCall.isSwitchCameraSupported()) {
mSwichRearFrontCameraImageView.setVisibility(View.VISIBLE);

boolean isSwitched= mCall.isCameraSwitched();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public void onCallAnsweredElsewhere() {
}

@Override
public void onCallEnd() {
public void onCallEnd(final int aReasonId) {
onCallTerminated();
}
};
Expand Down
2 changes: 2 additions & 0 deletions vector/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,8 @@
<string name="call_error_ice_failed">Media Connection Failed</string>
<string name="call_error_camera_init_failed">Cannot initialize the camera</string>
<string name="call_error_answered_elsewhere">call answered elsewhere</string>
<string name="call_error_peer_hangup">peer hung up</string>
<string name="call_error_peer_hangup_elsewhere">call hung up elsewhere</string>

<string name="action_accept">ACCEPT</string>
<string name="action_ignore">IGNORE</string>
Expand Down

0 comments on commit 70832eb

Please sign in to comment.