From 6a1df0538e0c49a9a063fa8e1d88d8986b24760d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 9 Apr 2020 19:45:21 +0200 Subject: [PATCH] request recording permission when making or accepting audio calls --- .../ui/ConversationFragment.java | 15 +++++- .../conversations/ui/RtpSessionActivity.java | 51 +++++++++++++++++-- .../conversations/utils/PermissionUtils.java | 26 ++++++++++ 3 files changed, 85 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index ba531cc45..e1638b6db 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -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; diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index 7890bfdbe..fd7614e99 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -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 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) { diff --git a/src/main/java/eu/siacs/conversations/utils/PermissionUtils.java b/src/main/java/eu/siacs/conversations/utils/PermissionUtils.java index 706b6c2f8..852dedc00 100644 --- a/src/main/java/eu/siacs/conversations/utils/PermissionUtils.java +++ b/src/main/java/eu/siacs/conversations/utils/PermissionUtils.java @@ -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 permissions, final int requestCode) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + final ImmutableList.Builder missingPermissions = new ImmutableList.Builder<>(); + for (final String permission : permissions) { + if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) { + missingPermissions.add(permission); + } + } + final ImmutableList missing = missingPermissions.build(); + if (missing.size() == 0) { + return true; + } + ActivityCompat.requestPermissions(activity, missing.toArray(new String[0]), requestCode); + return false; + } else { + return true; + } + } }