request recording permission when making or accepting audio calls

This commit is contained in:
Daniel Gultsch 2020-04-09 19:45:21 +02:00
parent 7749a7ce22
commit 6a1df0538e
3 changed files with 85 additions and 7 deletions

View file

@ -109,6 +109,7 @@ import eu.siacs.conversations.utils.GeoHelper;
import eu.siacs.conversations.utils.MessageUtils; import eu.siacs.conversations.utils.MessageUtils;
import eu.siacs.conversations.utils.NickValidityChecker; import eu.siacs.conversations.utils.NickValidityChecker;
import eu.siacs.conversations.utils.Patterns; import eu.siacs.conversations.utils.Patterns;
import eu.siacs.conversations.utils.PermissionUtils;
import eu.siacs.conversations.utils.QuickLoader; import eu.siacs.conversations.utils.QuickLoader;
import eu.siacs.conversations.utils.StylingHelper; import eu.siacs.conversations.utils.StylingHelper;
import eu.siacs.conversations.utils.TimeframeUtils; 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_START_DOWNLOAD = 0x0210;
public static final int REQUEST_ADD_EDITOR_CONTENT = 0x0211; public static final int REQUEST_ADD_EDITOR_CONTENT = 0x0211;
public static final int REQUEST_COMMIT_ATTACHMENTS = 0x0212; 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_CHOOSE_IMAGE = 0x0301;
public static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302; public static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302;
public static final int ATTACHMENT_CHOICE_CHOOSE_FILE = 0x0303; public static final int ATTACHMENT_CHOICE_CHOOSE_FILE = 0x0303;
@ -1233,7 +1235,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
} }
break; break;
case R.id.action_call: case R.id.action_call:
triggerRtpSession(); checkPermissionAndTriggerRtpSession();
break; break;
default: default:
break; break;
@ -1241,6 +1243,12 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
private void checkPermissionAndTriggerRtpSession() {
if (hasPermissions(REQUEST_START_AUDIO_CALL, Manifest.permission.RECORD_AUDIO)) {
triggerRtpSession();
}
}
private void triggerRtpSession() { private void triggerRtpSession() {
final Contact contact = conversation.getContact(); final Contact contact = conversation.getContact();
final Intent intent = new Intent(activity, RtpSessionActivity.class); final Intent intent = new Intent(activity, RtpSessionActivity.class);
@ -1383,7 +1391,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
} }
@Override @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 (grantResults.length > 0) {
if (allGranted(grantResults)) { if (allGranted(grantResults)) {
switch (requestCode) { switch (requestCode) {
@ -1400,6 +1408,9 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
case REQUEST_COMMIT_ATTACHMENTS: case REQUEST_COMMIT_ATTACHMENTS:
commitAttachments(); commitAttachments();
break; break;
case REQUEST_START_AUDIO_CALL:
triggerRtpSession();
break;
default: default:
attachFile(requestCode); attachFile(requestCode);
break; break;

View file

@ -1,14 +1,24 @@
package eu.siacs.conversations.ui; package eu.siacs.conversations.ui;
import android.Manifest;
import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.content.res.ColorStateList; import android.content.pm.PackageManager;
import android.databinding.DataBindingUtil; import android.databinding.DataBindingUtil;
import android.os.Build;
import android.os.Bundle; 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.util.Log;
import android.view.View; import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.Toast;
import com.google.common.collect.ImmutableList;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.List;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; 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.Account;
import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.services.XmppConnectionService; 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.AbstractJingleConnection;
import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection; import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection;
import eu.siacs.conversations.xmpp.jingle.RtpEndUserState; import eu.siacs.conversations.xmpp.jingle.RtpEndUserState;
import rocks.xmpp.addr.Jid; import rocks.xmpp.addr.Jid;
import static eu.siacs.conversations.utils.PermissionUtils.getFirstDenied;
import static java.util.Arrays.asList; 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 dont automatically call again on recreate //TODO if last state was BUSY (or RETRY); we want to reset action to view or something so we dont automatically call again on recreate
public class RtpSessionActivity extends XmppActivity implements XmppConnectionService.OnJingleRtpConnectionUpdate { 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_WITH = "with";
public static final String EXTRA_SESSION_ID = "session_id"; public static final String EXTRA_SESSION_ID = "session_id";
public static final String EXTRA_LAST_REPORTED_STATE = "last_reported_state"; public static final String EXTRA_LAST_REPORTED_STATE = "last_reported_state";
@ -75,8 +89,14 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
} }
private void acceptCall(View view) { private void acceptCall(View view) {
requestPermissionsAndAcceptCall();
}
private void requestPermissionsAndAcceptCall() {
if (PermissionUtils.hasPermission(this, ImmutableList.of(Manifest.permission.RECORD_AUDIO), REQUEST_ACCEPT_CALL)) {
requireRtpConnection().acceptCall(); requireRtpConnection().acceptCall();
} }
}
@Override @Override
protected void refreshUiReal() { protected void refreshUiReal() {
@ -89,7 +109,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
//TODO reinitialize //TODO reinitialize
if (ACTION_ACCEPT_CALL.equals(intent.getAction())) { if (ACTION_ACCEPT_CALL.equals(intent.getAction())) {
Log.d(Config.LOGTAG, "accepting through onNewIntent()"); 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); initializeActivityWithRunningRapSession(account, with, sessionId);
if (ACTION_ACCEPT_CALL.equals(intent.getAction())) { if (ACTION_ACCEPT_CALL.equals(intent.getAction())) {
Log.d(Config.LOGTAG, "intent action was accept"); 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())) { } else if (asList(ACTION_MAKE_VIDEO_CALL, ACTION_MAKE_VOICE_CALL).contains(intent.getAction())) {
xmppConnectionService.getJingleConnectionManager().proposeJingleRtpSession(account, with); 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) { private void initializeActivityWithRunningRapSession(final Account account, Jid with, String sessionId) {
final WeakReference<JingleRtpConnection> reference = xmppConnectionService.getJingleConnectionManager() final WeakReference<JingleRtpConnection> reference = xmppConnectionService.getJingleConnectionManager()
@ -226,7 +267,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
} }
private void retry(View view) { private void retry(View view) {
Log.d(Config.LOGTAG,"attempting retry"); Log.d(Config.LOGTAG, "attempting retry");
} }
private void exit(View view) { private void exit(View view) {

View file

@ -1,7 +1,14 @@
package eu.siacs.conversations.utils; package eu.siacs.conversations.utils;
import android.Manifest; import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager; 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 { public class PermissionUtils {
@ -31,4 +38,23 @@ public class PermissionUtils {
} }
return null; 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;
}
}
} }