@@ -109,6 +109,7 @@ import eu.siacs.conversations.utils.GeoHelper;
import eu.siacs.conversations.utils.MessageUtils;
import eu.siacs.conversations.utils.NickValidityChecker;
import eu.siacs.conversations.utils.Patterns;
+import eu.siacs.conversations.utils.PermissionUtils;
import eu.siacs.conversations.utils.QuickLoader;
import eu.siacs.conversations.utils.StylingHelper;
import eu.siacs.conversations.utils.TimeframeUtils;
@@ -138,6 +139,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
public static final int REQUEST_START_DOWNLOAD = 0x0210;
public static final int REQUEST_ADD_EDITOR_CONTENT = 0x0211;
public static final int REQUEST_COMMIT_ATTACHMENTS = 0x0212;
+ public static final int REQUEST_START_AUDIO_CALL = 0x213;
public static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301;
public static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302;
public static final int ATTACHMENT_CHOICE_CHOOSE_FILE = 0x0303;
@@ -1233,7 +1235,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
}
break;
case R.id.action_call:
- triggerRtpSession();
+ checkPermissionAndTriggerRtpSession();
break;
default:
break;
@@ -1241,6 +1243,12 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
return super.onOptionsItemSelected(item);
}
+ private void checkPermissionAndTriggerRtpSession() {
+ if (hasPermissions(REQUEST_START_AUDIO_CALL, Manifest.permission.RECORD_AUDIO)) {
+ triggerRtpSession();
+ }
+ }
+
private void triggerRtpSession() {
final Contact contact = conversation.getContact();
final Intent intent = new Intent(activity, RtpSessionActivity.class);
@@ -1383,7 +1391,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
}
@Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (grantResults.length > 0) {
if (allGranted(grantResults)) {
switch (requestCode) {
@@ -1400,6 +1408,9 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
case REQUEST_COMMIT_ATTACHMENTS:
commitAttachments();
break;
+ case REQUEST_START_AUDIO_CALL:
+ triggerRtpSession();
+ break;
default:
attachFile(requestCode);
break;
@@ -1,14 +1,24 @@
package eu.siacs.conversations.ui;
+import android.Manifest;
+import android.app.Activity;
import android.content.Intent;
-import android.content.res.ColorStateList;
+import android.content.pm.PackageManager;
import android.databinding.DataBindingUtil;
+import android.os.Build;
import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.StringRes;
+import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
+import android.widget.Toast;
+
+import com.google.common.collect.ImmutableList;
import java.lang.ref.WeakReference;
+import java.util.List;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
@@ -16,17 +26,21 @@ import eu.siacs.conversations.databinding.ActivityRtpSessionBinding;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.utils.PermissionUtils;
import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection;
import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection;
import eu.siacs.conversations.xmpp.jingle.RtpEndUserState;
import rocks.xmpp.addr.Jid;
+import static eu.siacs.conversations.utils.PermissionUtils.getFirstDenied;
import static java.util.Arrays.asList;
//TODO if last state was BUSY (or RETRY); we want to reset action to view or something so we donβt automatically call again on recreate
public class RtpSessionActivity extends XmppActivity implements XmppConnectionService.OnJingleRtpConnectionUpdate {
+ private static final int REQUEST_ACCEPT_CALL = 0x1111;
+
public static final String EXTRA_WITH = "with";
public static final String EXTRA_SESSION_ID = "session_id";
public static final String EXTRA_LAST_REPORTED_STATE = "last_reported_state";
@@ -75,7 +89,13 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
}
private void acceptCall(View view) {
- requireRtpConnection().acceptCall();
+ requestPermissionsAndAcceptCall();
+ }
+
+ private void requestPermissionsAndAcceptCall() {
+ if (PermissionUtils.hasPermission(this, ImmutableList.of(Manifest.permission.RECORD_AUDIO), REQUEST_ACCEPT_CALL)) {
+ requireRtpConnection().acceptCall();
+ }
}
@Override
@@ -89,7 +109,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
//TODO reinitialize
if (ACTION_ACCEPT_CALL.equals(intent.getAction())) {
Log.d(Config.LOGTAG, "accepting through onNewIntent()");
- requireRtpConnection().acceptCall();
+ requestPermissionsAndAcceptCall();
}
}
@@ -103,7 +123,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
initializeActivityWithRunningRapSession(account, with, sessionId);
if (ACTION_ACCEPT_CALL.equals(intent.getAction())) {
Log.d(Config.LOGTAG, "intent action was accept");
- requireRtpConnection().acceptCall();
+ requestPermissionsAndAcceptCall();
}
} else if (asList(ACTION_MAKE_VIDEO_CALL, ACTION_MAKE_VOICE_CALL).contains(intent.getAction())) {
xmppConnectionService.getJingleConnectionManager().proposeJingleRtpSession(account, with);
@@ -120,6 +140,27 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
}
}
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (PermissionUtils.allGranted(grantResults)) {
+ if (requestCode == REQUEST_ACCEPT_CALL) {
+ requireRtpConnection().acceptCall();
+ }
+ } else {
+ @StringRes int res;
+ final String firstDenied = getFirstDenied(grantResults, permissions);
+ if (Manifest.permission.RECORD_AUDIO.equals(firstDenied)) {
+ res = R.string.no_microphone_permission;
+ } else if (Manifest.permission.CAMERA.equals(firstDenied)) {
+ res = R.string.no_camera_permission;
+ } else {
+ throw new IllegalStateException("Invalid permission result request");
+ }
+ Toast.makeText(this, res, Toast.LENGTH_SHORT).show();
+ }
+ }
+
private void initializeActivityWithRunningRapSession(final Account account, Jid with, String sessionId) {
final WeakReference<JingleRtpConnection> reference = xmppConnectionService.getJingleConnectionManager()
@@ -226,7 +267,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
}
private void retry(View view) {
- Log.d(Config.LOGTAG,"attempting retry");
+ Log.d(Config.LOGTAG, "attempting retry");
}
private void exit(View view) {
@@ -1,7 +1,14 @@
package eu.siacs.conversations.utils;
import android.Manifest;
+import android.app.Activity;
import android.content.pm.PackageManager;
+import android.os.Build;
+import android.support.v4.app.ActivityCompat;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
public class PermissionUtils {
@@ -31,4 +38,23 @@ public class PermissionUtils {
}
return null;
}
+
+ public static boolean hasPermission(final Activity activity, final List<String> permissions, final int requestCode) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ final ImmutableList.Builder<String> missingPermissions = new ImmutableList.Builder<>();
+ for (final String permission : permissions) {
+ if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
+ missingPermissions.add(permission);
+ }
+ }
+ final ImmutableList<String> missing = missingPermissions.build();
+ if (missing.size() == 0) {
+ return true;
+ }
+ ActivityCompat.requestPermissions(activity, missing.toArray(new String[0]), requestCode);
+ return false;
+ } else {
+ return true;
+ }
+ }
}