diff --git a/app/build.gradle b/app/build.gradle index 08f07a9..2acd24e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "com.sendbird.calls.quickstart" minSdkVersion 16 // [Calls] targetSdkVersion 29 - versionCode 6 - versionName "1.1.3" + versionCode 7 + versionName "1.2.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -31,9 +31,9 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'com.google.android.material:material:1.1.0' - implementation 'com.sendbird.sdk:sendbird-calls:1.1.3' // [Calls] - implementation 'com.google.firebase:firebase-core:17.4.3' // [Calls] FCM - implementation 'com.google.firebase:firebase-messaging:20.2.0' // [Calls] FCM + implementation 'com.sendbird.sdk:sendbird-calls:1.2.0' // [Calls] + implementation 'com.google.firebase:firebase-core:17.4.4' // [Calls] FCM + implementation 'com.google.firebase:firebase-messaging:20.2.3' // [Calls] FCM implementation 'com.github.bumptech.glide:glide:4.11.0' //+ [QRCode] diff --git a/app/src/main/java/com/sendbird/calls/quickstart/BaseApplication.java b/app/src/main/java/com/sendbird/calls/quickstart/BaseApplication.java index 7ff71b4..1840773 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/BaseApplication.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/BaseApplication.java @@ -10,17 +10,17 @@ import com.sendbird.calls.SendBirdCall; import com.sendbird.calls.handler.DirectCallListener; import com.sendbird.calls.handler.SendBirdCallListener; -import com.sendbird.calls.quickstart.call.CallActivity; import com.sendbird.calls.quickstart.call.CallService; +import com.sendbird.calls.quickstart.utils.BroadcastUtils; import com.sendbird.calls.quickstart.utils.PrefUtils; import java.util.UUID; public class BaseApplication extends Application { - public static final String VERSION = "1.1.3"; + public static final String VERSION = "1.2.0"; - private static final String TAG = "BaseApplication"; + public static final String TAG = "SendBirdCalls"; // Refer to "https://github.com/sendbird/quickstart-calls-android". public static final String APP_ID = "YOUR_APPLICATION_ID"; @@ -28,13 +28,13 @@ public class BaseApplication extends Application { @Override public void onCreate() { super.onCreate(); - Log.d(TAG, "onCreate()"); + Log.i(BaseApplication.TAG, "[BaseApplication] onCreate()"); initSendBirdCall(PrefUtils.getAppId(getApplicationContext())); } public boolean initSendBirdCall(String appId) { - Log.d(TAG, "initSendBirdCall(appId: " + appId + ")"); + Log.i(BaseApplication.TAG, "[BaseApplication] initSendBirdCall(appId: " + appId + ")"); Context context = getApplicationContext(); if (TextUtils.isEmpty(appId)) { @@ -46,8 +46,10 @@ public boolean initSendBirdCall(String appId) { SendBirdCall.addListener(UUID.randomUUID().toString(), new SendBirdCallListener() { @Override public void onRinging(DirectCall call) { - Log.d(TAG, "onRinging() => callId: " + call.getCallId()); - if (CallActivity.sIsRunning) { + int ongoingCallCount = SendBirdCall.getOngoingCallCount(); + Log.i(BaseApplication.TAG, "[BaseApplication] onRinging() => callId: " + call.getCallId() + ", getOngoingCallCount(): " + ongoingCallCount); + + if (ongoingCallCount >= 2) { call.end(); return; } @@ -59,13 +61,18 @@ public void onConnected(DirectCall call) { @Override public void onEnded(DirectCall call) { - if (!CallActivity.sIsRunning) { + int ongoingCallCount = SendBirdCall.getOngoingCallCount(); + Log.i(BaseApplication.TAG, "[BaseApplication] onEnded() => callId: " + call.getCallId() + ", getOngoingCallCount(): " + ongoingCallCount); + + BroadcastUtils.sendCallLogBroadcast(context, call.getCallLog()); + + if (ongoingCallCount == 0) { CallService.stopService(context); } } }); - CallService.startService(context, call, true); + CallService.onRinging(context, call); } }); return true; diff --git a/app/src/main/java/com/sendbird/calls/quickstart/SignInManuallyActivity.java b/app/src/main/java/com/sendbird/calls/quickstart/SignInManuallyActivity.java index 500c964..b132426 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/SignInManuallyActivity.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/SignInManuallyActivity.java @@ -1,6 +1,5 @@ package com.sendbird.calls.quickstart; -import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.text.Editable; @@ -24,7 +23,6 @@ public class SignInManuallyActivity extends AppCompatActivity { private Context mContext; - private Activity mParentActivity; private InputMethodManager mInputMethodManager; private TextInputLayout mTextInputLayoutAppId; @@ -41,7 +39,6 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_sign_in_manually); mContext = this; - mParentActivity = getParent(); mInputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); initViews(); diff --git a/app/src/main/java/com/sendbird/calls/quickstart/call/CallActivity.java b/app/src/main/java/com/sendbird/calls/quickstart/call/CallActivity.java index 67deb42..01a367d 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/call/CallActivity.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/call/CallActivity.java @@ -1,11 +1,13 @@ package com.sendbird.calls.quickstart.call; import android.annotation.TargetApi; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageManager; +import android.content.ServiceConnection; import android.os.Build; import android.os.Bundle; +import android.os.IBinder; import android.util.Log; import android.view.View; import android.view.WindowManager; @@ -14,7 +16,6 @@ import android.widget.RelativeLayout; import android.widget.TextView; -import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import com.sendbird.calls.AudioDevice; @@ -22,27 +23,21 @@ import com.sendbird.calls.DirectCallUser; import com.sendbird.calls.SendBirdCall; import com.sendbird.calls.handler.DirectCallListener; +import com.sendbird.calls.quickstart.BaseApplication; import com.sendbird.calls.quickstart.R; import com.sendbird.calls.quickstart.utils.AuthenticationUtils; import com.sendbird.calls.quickstart.utils.BroadcastUtils; import com.sendbird.calls.quickstart.utils.UserInfoUtils; -import java.util.ArrayList; import java.util.Set; import java.util.Timer; import java.util.TimerTask; public abstract class CallActivity extends AppCompatActivity { - public static boolean sIsRunning; - - private static final String TAG = "CallActivity"; - static final int ENDING_TIME_MS = 1000; - static final int REQUEST_PERMISSIONS_REQUEST_CODE = 1; - enum STATE { - STATE_INCOMING, + public enum STATE { STATE_ACCEPTING, STATE_OUTGOING, STATE_CONNECTED, @@ -51,15 +46,20 @@ enum STATE { } Context mContext; - private String mIncomingCallId; - private boolean mIsEnd; - private Timer mEndingTimer; STATE mState; - String mCalleeId; + private String mCallId; boolean mIsVideoCall; + String mCalleeIdToDial; + private boolean mDoDial; + private boolean mDoAccept; + protected boolean mDoLocalVideoStart; + + private boolean mDoEnd; + DirectCall mDirectCall; - boolean mIsAudioEnabled = true; + boolean mIsAudioEnabled; + private Timer mEndingTimer; //+ Views LinearLayout mLinearLayoutInfo; @@ -72,7 +72,6 @@ enum STATE { RelativeLayout mRelativeLayoutRingingButtons; ImageView mImageViewDecline; - ImageView mImageViewAccept; LinearLayout mLinearLayoutConnectingButtons; ImageView mImageViewAudioOff; @@ -82,15 +81,20 @@ enum STATE { //+ abstract methods protected abstract int getLayoutResourceId(); - protected abstract String[] getMandatoryPermissions(); - protected abstract void audioDeviceChanged(DirectCall call, AudioDevice currentAudioDevice, Set availableAudioDevices); + protected abstract void setAudioDevice(AudioDevice currentAudioDevice, Set availableAudioDevices); protected abstract void startCall(boolean amICallee); //- abstract methods + //+ CallService + private CallService mCallService; + private boolean mBound = false; + //- CallService + + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Log.d(TAG, "onCreate()"); + Log.i(BaseApplication.TAG, "[CallActivity] onCreate()"); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED @@ -99,47 +103,56 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(getLayoutResourceId()); mContext = this; - sIsRunning = true; + bindCallService(); + + init(); initViews(); setViews(); + setAudioDevice(); + setCurrentState(); - init(getIntent()); + if (mDoEnd) { + Log.i(BaseApplication.TAG, "[CallActivity] init() => (mDoEnd == true)"); + end(); + return; + } + + checkAuthentication(); } - private void init(Intent intent) { - mIncomingCallId = intent.getStringExtra(CallService.EXTRA_CALL_ID); - mIsEnd = intent.getBooleanExtra(CallService.EXTRA_IS_END, false); + private void init() { + Intent intent = getIntent(); - if (mIsEnd) { - CallService.stopService(mContext); - } + mState = (STATE) intent.getSerializableExtra(CallService.EXTRA_CALL_STATE); + mCallId = intent.getStringExtra(CallService.EXTRA_CALL_ID); + mIsVideoCall = intent.getBooleanExtra(CallService.EXTRA_IS_VIDEO_CALL, false); + mCalleeIdToDial = intent.getStringExtra(CallService.EXTRA_CALLEE_ID_TO_DIAL); + mDoDial = intent.getBooleanExtra(CallService.EXTRA_DO_DIAL, false); + mDoAccept = intent.getBooleanExtra(CallService.EXTRA_DO_ACCEPT, false); + mDoLocalVideoStart = intent.getBooleanExtra(CallService.EXTRA_DO_LOCAL_VIDEO_START, false); - if (mIncomingCallId != null) { // as callee - mDirectCall = SendBirdCall.getCall(mIncomingCallId); - mCalleeId = mDirectCall.getCallee().getUserId(); - mIsVideoCall = mDirectCall.isVideoCall(); + mDoEnd = intent.getBooleanExtra(CallService.EXTRA_DO_END, false); - setListener(mDirectCall); - } else { // as caller - mCalleeId = intent.getStringExtra(CallService.EXTRA_CALLEE_ID); - mIsVideoCall = intent.getBooleanExtra(CallService.EXTRA_IS_VIDEO_CALL, false); - } + Log.i(BaseApplication.TAG, "[CallActivity] init() => (mState: " + mState + ", mCallId: " + mCallId + ", mIsVideoCall: " + mIsVideoCall + + ", mCalleeIdToDial: " + mCalleeIdToDial + ", mDoDial: " + mDoDial + ", mDoAccept: " + mDoAccept + ", mDoLocalVideoStart: " + mDoLocalVideoStart + + ", mDoEnd: " + mDoEnd + ")"); - if (setInitialState()) { - checkAuthenticate(); + if (mCallId != null) { + mDirectCall = SendBirdCall.getCall(mCallId); + setListener(mDirectCall); } } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - Log.d(TAG, "onNewIntent()"); + Log.i(BaseApplication.TAG, "[CallActivity] onNewIntent()"); - mIsEnd = intent.getBooleanExtra(CallService.EXTRA_IS_END, false); - if (mIsEnd) { - CallService.stopService(mContext); - end(mDirectCall); + mDoEnd = intent.getBooleanExtra(CallService.EXTRA_DO_END, false); + if (mDoEnd) { + Log.i(BaseApplication.TAG, "[CallActivity] onNewIntent() => (mDoEnd == true)"); + end(); } } @@ -154,7 +167,6 @@ protected void initViews() { mRelativeLayoutRingingButtons = findViewById(R.id.relative_layout_ringing_buttons); mImageViewDecline = findViewById(R.id.image_view_decline); - mImageViewAccept = findViewById(R.id.image_view_accept); mLinearLayoutConnectingButtons = findViewById(R.id.linear_layout_connecting_buttons); mImageViewAudioOff = findViewById(R.id.image_view_audio_off); @@ -164,28 +176,14 @@ protected void initViews() { protected void setViews() { mImageViewDecline.setOnClickListener(view -> { - end(mDirectCall); - }); - - mImageViewAccept.setOnClickListener(view -> { - if (SendBirdCall.getCurrentUser() == null) { - Log.d(TAG, "mImageViewAccept clicked => (SendBirdCall.getCurrentUser() == null)"); - return; - } - - if (mState == STATE.STATE_ENDING || mState == STATE.STATE_ENDED) { - Log.d(TAG, "mImageViewAccept clicked => Already ending call."); - return; - } - - if (mState == STATE.STATE_ACCEPTING) { - Log.d(TAG, "mImageViewAccept clicked => Already accepting call."); - return; - } - - setState(STATE.STATE_ACCEPTING, mDirectCall); + end(); }); + if (mDirectCall != null) { + mIsAudioEnabled = mDirectCall.isLocalAudioEnabled(); + } else { + mIsAudioEnabled = true; + } if (mIsAudioEnabled) { mImageViewAudioOff.setSelected(false); } else { @@ -194,12 +192,12 @@ protected void setViews() { mImageViewAudioOff.setOnClickListener(view -> { if (mDirectCall != null) { if (mIsAudioEnabled) { - Log.d(TAG, "mute()"); + Log.i(BaseApplication.TAG, "[CallActivity] mute()"); mDirectCall.muteMicrophone(); mIsAudioEnabled = false; mImageViewAudioOff.setSelected(true); } else { - Log.d(TAG, "unmute()"); + Log.i(BaseApplication.TAG, "[CallActivity] unmute()"); mDirectCall.unmuteMicrophone(); mIsAudioEnabled = true; mImageViewAudioOff.setSelected(false); @@ -208,45 +206,65 @@ protected void setViews() { }); mImageViewEnd.setOnClickListener(view -> { - end(mDirectCall); + end(); }); } + private void setAudioDevice() { + if (mDirectCall != null) { + setAudioDevice(mDirectCall.getCurrentAudioDevice(), mDirectCall.getAvailableAudioDevices()); + } + } + + private void setCurrentState() { + setState(mState, mDirectCall); + } + protected void setListener(DirectCall call) { - Log.d(TAG, "setListener()"); + Log.i(BaseApplication.TAG, "[CallActivity] setListener()"); - call.setListener(new DirectCallListener() { - @Override - public void onConnected(DirectCall call) { - Log.d(TAG, "onConnected()"); - setState(STATE.STATE_CONNECTED, call); - } + if (call != null) { + call.setListener(new DirectCallListener() { + @Override + public void onConnected(DirectCall call) { + Log.i(BaseApplication.TAG, "[CallActivity] onConnected()"); + setState(STATE.STATE_CONNECTED, call); + } - @Override - public void onEnded(DirectCall call) { - Log.d(TAG, "onEnded()"); - setState(STATE.STATE_ENDED, call); + @Override + public void onEnded(DirectCall call) { + Log.i(BaseApplication.TAG, "[CallActivity] onEnded()"); + setState(STATE.STATE_ENDED, call); - BroadcastUtils.sendCallLogBroadcast(mContext, call.getCallLog()); - } + BroadcastUtils.sendCallLogBroadcast(mContext, call.getCallLog()); + } - @Override - public void onRemoteVideoSettingsChanged(DirectCall call) { - Log.d(TAG, "onRemoteVideoSettingsChanged()"); - } + @Override + public void onRemoteVideoSettingsChanged(DirectCall call) { + Log.i(BaseApplication.TAG, "[CallActivity] onRemoteVideoSettingsChanged()"); + } - @Override - public void onRemoteAudioSettingsChanged(DirectCall call) { - Log.d(TAG, "onRemoteAudioSettingsChanged()"); - setRemoteMuteInfo(call); - } + @Override + public void onLocalVideoSettingsChanged(DirectCall call) { + Log.i(BaseApplication.TAG, "[CallActivity] onLocalVideoSettingsChanged()"); + if (CallActivity.this instanceof VideoCallActivity) { + ((VideoCallActivity) CallActivity.this).setLocalVideoSettings(call); + } + } - @Override - public void onAudioDeviceChanged(DirectCall call, AudioDevice currentAudioDevice, Set availableAudioDevices) { - Log.d(TAG, "onAudioDeviceChanged(currentAudioDevice: " + currentAudioDevice + ", availableAudioDevices: " + availableAudioDevices + ")"); - audioDeviceChanged(call, currentAudioDevice, availableAudioDevices); - } - }); + @Override + public void onRemoteAudioSettingsChanged(DirectCall call) { + Log.i(BaseApplication.TAG, "[CallActivity] onRemoteAudioSettingsChanged()"); + setRemoteMuteInfo(call); + } + + @Override + public void onAudioDeviceChanged(DirectCall call, AudioDevice currentAudioDevice, Set availableAudioDevices) { + Log.i(BaseApplication.TAG, "[CallActivity] onAudioDeviceChanged(currentAudioDevice: " + currentAudioDevice + ", availableAudioDevices: " + availableAudioDevices + ")"); + setAudioDevice(currentAudioDevice, availableAudioDevices); + } + }); + } } @TargetApi(19) @@ -258,97 +276,36 @@ private static int getSystemUiVisibility() { return flags; } - private boolean setInitialState() { - if (mIncomingCallId != null) { - Log.d(TAG, "setInitialState() => (mIncomingCallId != null)"); - - if (mDirectCall.isEnded()) { - Log.d(TAG, "setInitialState() => (mDirectCall.isEnded() == true)"); - setState(STATE.STATE_ENDED, mDirectCall); - return false; - } - - CallService.startService(mContext, mDirectCall, false); - - setState(STATE.STATE_INCOMING, mDirectCall); - } else { - setState(STATE.STATE_OUTGOING, mDirectCall); - } - return true; - } - - private void checkAuthenticate() { + private void checkAuthentication() { if (SendBirdCall.getCurrentUser() == null) { AuthenticationUtils.autoAuthenticate(mContext, userId -> { if (userId == null) { finishWithEnding("autoAuthenticate() failed."); return; } - checkPermissions(); + ready(); }); - } else { - checkPermissions(); - } - } - - private void checkPermissions() { - ArrayList deniedPermissions = new ArrayList<>(); - for (String permission : getMandatoryPermissions()) { - if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { - deniedPermissions.add(permission); - } - } - - if (deniedPermissions.size() > 0) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - requestPermissions(deniedPermissions.toArray(new String[0]), REQUEST_PERMISSIONS_REQUEST_CODE); - } else { - finishWithEnding("Permission denied."); - } } else { ready(); } } - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) { - boolean allowed = true; - - for (int result : grantResults) { - allowed = allowed && (result == PackageManager.PERMISSION_GRANTED); - } - - if (allowed) { - ready(); - } else { - finishWithEnding("Permission denied."); - } - } - } - private void ready() { - if (mIsEnd) { - end(mDirectCall); - return; - } - - if (mState == STATE.STATE_OUTGOING) { + if (mDoDial) { + mDoDial = false; startCall(false); - } else if (mState == STATE.STATE_INCOMING) { - setState(STATE.STATE_ACCEPTING, mDirectCall); + } else if (mDoAccept) { + mDoAccept = false; + startCall(true); } } protected boolean setState(STATE state, DirectCall call) { - if (isFinishing()) { - Log.d(TAG, "setState() => isFinishing()"); - return false; - } - mState = state; + updateCallService(); + switch (state) { - case STATE_INCOMING: { + case STATE_ACCEPTING: { mLinearLayoutInfo.setVisibility(View.VISIBLE); mLinearLayoutRemoteMute.setVisibility(View.GONE); mRelativeLayoutRingingButtons.setVisibility(View.VISIBLE); @@ -361,11 +318,7 @@ protected boolean setState(STATE state, DirectCall call) { } mImageViewDecline.setBackgroundResource(R.drawable.btn_call_decline); - break; - } - case STATE_ACCEPTING: { - startCall(true); setInfo(call, getString(R.string.calls_connecting_call)); break; } @@ -396,6 +349,12 @@ protected boolean setState(STATE state, DirectCall call) { } case STATE_ENDING: { + mLinearLayoutInfo.setVisibility(View.VISIBLE); + mImageViewProfile.setVisibility(View.VISIBLE); + mLinearLayoutRemoteMute.setVisibility(View.GONE); + mRelativeLayoutRingingButtons.setVisibility(View.GONE); + mLinearLayoutConnectingButtons.setVisibility(View.GONE); + if (mIsVideoCall) { setInfo(call, getString(R.string.calls_ending_video_call)); } else { @@ -424,21 +383,26 @@ protected void setInfo(DirectCall call, String status) { DirectCallUser remoteUser = (call != null ? call.getRemoteUser() : null); if (remoteUser != null) { UserInfoUtils.setProfileImage(mContext, remoteUser, mImageViewProfile); - UserInfoUtils.setNicknameOrUserId(remoteUser, mTextViewUserId); - } else { - mTextViewUserId.setText(mCalleeId); } + mTextViewUserId.setText(getRemoteNicknameOrUserId(call)); mTextViewStatus.setVisibility(View.VISIBLE); if (status != null) { mTextViewStatus.setText(status); } } + private String getRemoteNicknameOrUserId(DirectCall call) { + String remoteNicknameOrUserId = mCalleeIdToDial; + if (call != null) { + remoteNicknameOrUserId = UserInfoUtils.getNicknameOrUserId(call.getRemoteUser()); + } + return remoteNicknameOrUserId; + } + private void setRemoteMuteInfo(DirectCall call) { if (call != null && !call.isRemoteAudioEnabled() && call.getRemoteUser() != null) { - String remoteUserId = call.getRemoteUser().getUserId(); - mTextViewRemoteMute.setText(getString(R.string.calls_muted_this_call, remoteUserId)); + mTextViewRemoteMute.setText(getString(R.string.calls_muted_this_call, UserInfoUtils.getNicknameOrUserId(call.getRemoteUser()))); mLinearLayoutRemoteMute.setVisibility(View.VISIBLE); } else { mLinearLayoutRemoteMute.setVisibility(View.GONE); @@ -490,22 +454,29 @@ private String getEndResultString(DirectCall call) { public void onBackPressed() { } - protected void end(DirectCall call) { - if (call != null) { - Log.d(TAG, "end(callId: " + call.getCallId() + ")"); + private void end() { + if (mDirectCall != null) { + Log.i(BaseApplication.TAG, "[CallActivity] end()"); if (mState == STATE.STATE_ENDING || mState == STATE.STATE_ENDED) { - Log.d(TAG, "Already ending call."); + Log.i(BaseApplication.TAG, "[CallActivity] Already ending call."); return; } - setState(STATE.STATE_ENDING, call); - call.end(); + if (mDirectCall.isEnded()) { + setState(STATE.STATE_ENDED, mDirectCall); + } else { + setState(STATE.STATE_ENDING, mDirectCall); + mDirectCall.end(); + } + } else { + Log.i(BaseApplication.TAG, "[CallActivity] end() => (mDirectCall == null)"); + finishWithEnding("(mDirectCall == null)"); } } protected void finishWithEnding(String log) { - Log.d(TAG, "finishWithEnding(" + log + ")"); + Log.i(BaseApplication.TAG, "[CallActivity] finishWithEnding(" + log + ")"); if (mEndingTimer == null) { mEndingTimer = new Timer(); @@ -513,9 +484,11 @@ protected void finishWithEnding(String log) { @Override public void run() { runOnUiThread(() -> { - Log.d(TAG, "finish()"); + Log.i(BaseApplication.TAG, "[CallActivity] finish()"); finish(); - CallService.stopService(mContext); + + unbindCallService(); + stopCallService(); }); } }, ENDING_TIME_MS); @@ -525,7 +498,70 @@ public void run() { @Override protected void onDestroy() { super.onDestroy(); - Log.d(TAG, "onDestroy()"); - sIsRunning = false; + Log.i(BaseApplication.TAG, "[CallActivity] onDestroy()"); + + unbindCallService(); + } + + //+ CallService + private ServiceConnection mCallServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName componentName, IBinder iBinder) { + Log.i(BaseApplication.TAG, "[CallActivity] onServiceConnected()"); + + CallService.CallBinder callBinder = (CallService.CallBinder) iBinder; + mCallService = callBinder.getService(); + mBound = true; + + updateCallService(); + } + + @Override + public void onServiceDisconnected(ComponentName componentName) { + Log.i(BaseApplication.TAG, "[CallActivity] onServiceDisconnected()"); + + mBound = false; + } + }; + + private void bindCallService() { + Log.i(BaseApplication.TAG, "[CallActivity] bindCallService()"); + + bindService(new Intent(this, CallService.class), mCallServiceConnection, Context.BIND_AUTO_CREATE); + } + + private void unbindCallService() { + Log.i(BaseApplication.TAG, "[CallActivity] unbindCallService()"); + + if (mBound) { + unbindService(mCallServiceConnection); + mBound = false; + } + } + + private void stopCallService() { + Log.i(BaseApplication.TAG, "[CallActivity] stopCallService()"); + + CallService.stopService(mContext); + } + + protected void updateCallService() { + if (mCallService != null) { + Log.i(BaseApplication.TAG, "[CallActivity] updateCallService()"); + + CallService.ServiceData serviceData = new CallService.ServiceData(); + serviceData.isHeadsUpNotification = false; + serviceData.remoteNicknameOrUserId = getRemoteNicknameOrUserId(mDirectCall); + serviceData.callState = mState; + serviceData.callId = (mDirectCall != null ? mDirectCall.getCallId() : mCallId); + serviceData.isVideoCall = mIsVideoCall; + serviceData.calleeIdToDial = mCalleeIdToDial; + serviceData.doDial = mDoDial; + serviceData.doAccept = mDoAccept; + serviceData.doLocalVideoStart = mDoLocalVideoStart; + + mCallService.updateNotification(serviceData); + } } + //- CallService } diff --git a/app/src/main/java/com/sendbird/calls/quickstart/call/CallService.java b/app/src/main/java/com/sendbird/calls/quickstart/call/CallService.java index 418235e..e533482 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/call/CallService.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/call/CallService.java @@ -8,79 +8,152 @@ import android.content.Context; import android.content.Intent; import android.graphics.BitmapFactory; +import android.os.Binder; import android.os.Build; import android.os.IBinder; import android.util.Log; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; import com.sendbird.calls.DirectCall; +import com.sendbird.calls.SendBirdCall; +import com.sendbird.calls.quickstart.BaseApplication; import com.sendbird.calls.quickstart.R; import com.sendbird.calls.quickstart.utils.UserInfoUtils; public class CallService extends Service { - private static final String TAG = "CallService"; private static final int NOTIFICATION_ID = 1; - public static final String EXTRA_REMOTE_NICKNAME_OR_USER_ID = "remote_user_id"; + public static final String EXTRA_IS_HEADS_UP_NOTIFICATION = "is_heads_up_notification"; + public static final String EXTRA_REMOTE_NICKNAME_OR_USER_ID = "remote_nickname_or_user_id"; + public static final String EXTRA_CALL_STATE = "call_state"; public static final String EXTRA_CALL_ID = "call_id"; - public static final String EXTRA_CALLEE_ID = "callee_id"; public static final String EXTRA_IS_VIDEO_CALL = "is_video_call"; - public static final String EXTRA_IS_HEADS_UP_NOTIFICATION = "is_heads_up_notification"; - public static final String EXTRA_IS_END = "is_end"; + public static final String EXTRA_CALLEE_ID_TO_DIAL = "callee_id_to_dial"; + public static final String EXTRA_DO_DIAL = "do_dial"; + public static final String EXTRA_DO_ACCEPT = "do_accept"; + public static final String EXTRA_DO_LOCAL_VIDEO_START = "do_local_video_start"; + + public static final String EXTRA_DO_END = "do_end"; + private Context mContext; + private final IBinder mBinder = new CallBinder(); + private final ServiceData mServiceData = new ServiceData(); + + class CallBinder extends Binder { + CallService getService() { + return CallService.this; + } + } + + static class ServiceData { + boolean isHeadsUpNotification; + String remoteNicknameOrUserId; + CallActivity.STATE callState; + String callId; + boolean isVideoCall; + String calleeIdToDial; + boolean doDial; + boolean doAccept; + boolean doLocalVideoStart; + + ServiceData() { + } - private String mRemoteNicknameOrUserId; - private String mCallId; - private String mCalleeId; - private boolean mIsVideoCall; + ServiceData(ServiceData serviceData) { + set(serviceData); + } + + void set(ServiceData serviceData) { + this.isHeadsUpNotification = serviceData.isHeadsUpNotification; + this.remoteNicknameOrUserId = serviceData.remoteNicknameOrUserId; + this.callState = serviceData.callState; + this.callId = serviceData.callId; + this.isVideoCall = serviceData.isVideoCall; + this.calleeIdToDial = serviceData.calleeIdToDial; + this.doDial = serviceData.doDial; + this.doAccept = serviceData.doAccept; + this.doLocalVideoStart = serviceData.doLocalVideoStart; + } + } @Nullable @Override public IBinder onBind(Intent intent) { - return null; + Log.i(BaseApplication.TAG, "[CallService] onBind()"); + return mBinder; } @Override public void onCreate() { super.onCreate(); - Log.d(TAG, "onCreate()"); + Log.i(BaseApplication.TAG, "[CallService] onCreate()"); mContext = this; } @Override - public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "onStartCommand()"); - - mRemoteNicknameOrUserId = intent.getStringExtra(EXTRA_REMOTE_NICKNAME_OR_USER_ID); - mCallId = intent.getStringExtra(EXTRA_CALL_ID); - mCalleeId = intent.getStringExtra(EXTRA_CALLEE_ID); - mIsVideoCall = intent.getBooleanExtra(EXTRA_IS_VIDEO_CALL, false); - boolean isHeadsUpNotification = intent.getBooleanExtra(EXTRA_IS_HEADS_UP_NOTIFICATION, false); - - Notification notification = getNotification(isHeadsUpNotification, mRemoteNicknameOrUserId, true, mCallId, mCalleeId, mIsVideoCall); - startForeground(NOTIFICATION_ID, notification); + public void onDestroy() { + super.onDestroy(); + Log.i(BaseApplication.TAG, "[CallService] onDestroy()"); + } + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.i(BaseApplication.TAG, "[CallService] onStartCommand()"); + + mServiceData.isHeadsUpNotification = intent.getBooleanExtra(EXTRA_IS_HEADS_UP_NOTIFICATION, false); + mServiceData.remoteNicknameOrUserId = intent.getStringExtra(EXTRA_REMOTE_NICKNAME_OR_USER_ID); + mServiceData.callState = (CallActivity.STATE) intent.getSerializableExtra(EXTRA_CALL_STATE); + mServiceData.callId = intent.getStringExtra(EXTRA_CALL_ID); + mServiceData.isVideoCall = intent.getBooleanExtra(EXTRA_IS_VIDEO_CALL, false); + mServiceData.calleeIdToDial = intent.getStringExtra(EXTRA_CALLEE_ID_TO_DIAL); + mServiceData.doDial = intent.getBooleanExtra(EXTRA_DO_DIAL, false); + mServiceData.doAccept = intent.getBooleanExtra(EXTRA_DO_ACCEPT, false); + mServiceData.doLocalVideoStart = intent.getBooleanExtra(EXTRA_DO_LOCAL_VIDEO_START, false); + + updateNotification(mServiceData); return super.onStartCommand(intent, flags, startId); } @Override public void onTaskRemoved(Intent rootIntent) { super.onTaskRemoved(rootIntent); - Log.d(TAG, "onTaskRemoved()"); + Log.i(BaseApplication.TAG, "[CallService] onTaskRemoved()"); + + mServiceData.isHeadsUpNotification = true; + updateNotification(mServiceData); + } + + private static Intent getCallActivityIntent(Context context, ServiceData serviceData, boolean doEnd) { + final Intent intent; + if (serviceData.isVideoCall) { + intent = new Intent(context, VideoCallActivity.class); + } else { + intent = new Intent(context, VoiceCallActivity.class); + } - Notification notification = getNotification(true, mRemoteNicknameOrUserId, false, mCallId, mCalleeId, mIsVideoCall); - startForeground(NOTIFICATION_ID, notification); + intent.putExtra(EXTRA_CALL_STATE, serviceData.callState); + intent.putExtra(EXTRA_CALL_ID, serviceData.callId); + intent.putExtra(EXTRA_IS_VIDEO_CALL, serviceData.isVideoCall); + intent.putExtra(EXTRA_CALLEE_ID_TO_DIAL, serviceData.calleeIdToDial); + intent.putExtra(EXTRA_DO_DIAL, serviceData.doDial); + intent.putExtra(EXTRA_DO_ACCEPT, serviceData.doAccept); + intent.putExtra(EXTRA_DO_LOCAL_VIDEO_START, serviceData.doLocalVideoStart); + + intent.putExtra(EXTRA_DO_END, doEnd); + + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + return intent; } - private Notification getNotification(boolean isHeadsUpNotification, String remoteNicknameOrUserId, boolean hasCallButton, - String callId, String calleeId, boolean isVideoCall) { + private Notification getNotification(@NonNull ServiceData serviceData) { final String content; - if (isVideoCall) { + if (serviceData.isVideoCall) { content = mContext.getString(R.string.calls_notification_video_calling_content, mContext.getString(R.string.calls_app_name)); } else { content = mContext.getString(R.string.calls_notification_voice_calling_content, mContext.getString(R.string.calls_app_name)); @@ -92,7 +165,7 @@ private Notification getNotification(boolean isHeadsUpNotification, String remot if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { String channelName = mContext.getString(R.string.calls_app_name); NotificationChannel channel = new NotificationChannel(channelId, channelName, - isHeadsUpNotification ? NotificationManager.IMPORTANCE_HIGH : NotificationManager.IMPORTANCE_LOW); + serviceData.isHeadsUpNotification ? NotificationManager.IMPORTANCE_HIGH : NotificationManager.IMPORTANCE_LOW); NotificationManager notificationManager = mContext.getSystemService(NotificationManager.class); if (notificationManager != null) { @@ -100,70 +173,106 @@ private Notification getNotification(boolean isHeadsUpNotification, String remot } } - Intent callIntent = getCallIntent(mContext, callId, calleeId, isVideoCall, false); - Intent endIntent = getCallIntent(mContext, callId, calleeId, isVideoCall, true); + Intent callIntent = getCallActivityIntent(mContext, serviceData, false); PendingIntent callPendingIntent = PendingIntent.getActivity(mContext, (currentTime + 1), callIntent, 0); + + Intent endIntent = getCallActivityIntent(mContext, serviceData, true); PendingIntent endPendingIntent = PendingIntent.getActivity(mContext, (currentTime + 2), endIntent, 0); NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, channelId); - builder.setContentTitle(remoteNicknameOrUserId) + builder.setContentTitle(serviceData.remoteNicknameOrUserId) .setContentText(content) .setSmallIcon(R.drawable.ic_sendbird) .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.icon_push_oreo)) - .setPriority(isHeadsUpNotification ? NotificationCompat.PRIORITY_HIGH : NotificationCompat.PRIORITY_LOW) - .addAction(new NotificationCompat.Action(0, mContext.getString(R.string.calls_notification_end), endPendingIntent)); - - if (hasCallButton) { - builder.addAction(new NotificationCompat.Action(0, mContext.getString(R.string.calls_notification_call), callPendingIntent)); + .setPriority(serviceData.isHeadsUpNotification ? NotificationCompat.PRIORITY_HIGH : NotificationCompat.PRIORITY_LOW); + + if (SendBirdCall.getOngoingCallCount() > 0) { + if (serviceData.doAccept) { + builder.addAction(new NotificationCompat.Action(0, mContext.getString(R.string.calls_notification_decline), endPendingIntent)); + builder.addAction(new NotificationCompat.Action(0, mContext.getString(R.string.calls_notification_accept), callPendingIntent)); + } else { + builder.setContentIntent(callPendingIntent); + builder.addAction(new NotificationCompat.Action(0, mContext.getString(R.string.calls_notification_end), endPendingIntent)); + } } - return builder.build(); } - private static Intent getCallIntent(Context context, String callId, String calleeId, boolean isVideoCall, boolean isEnd) { - final Intent intent; - if (isVideoCall) { - intent = new Intent(context, VideoCallActivity.class); - } else { - intent = new Intent(context, VoiceCallActivity.class); - } + public static void dial(Context context, String doDialWithCalleeId, boolean isVideoCall) { + Log.i(BaseApplication.TAG, "[CallService] dial()"); - intent.putExtra(EXTRA_CALL_ID, callId); - intent.putExtra(EXTRA_CALLEE_ID, calleeId); - intent.putExtra(EXTRA_IS_VIDEO_CALL, isVideoCall); - intent.putExtra(EXTRA_IS_END, isEnd); + ServiceData serviceData = new ServiceData(); + serviceData.isHeadsUpNotification = false; + serviceData.remoteNicknameOrUserId = doDialWithCalleeId; + serviceData.callState = CallActivity.STATE.STATE_OUTGOING; + serviceData.callId = null; + serviceData.isVideoCall = isVideoCall; + serviceData.calleeIdToDial = doDialWithCalleeId; + serviceData.doDial = true; + serviceData.doAccept = false; + serviceData.doLocalVideoStart = false; - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - return intent; - } + startService(context, serviceData); - public static void startCallActivity(Context context, String calleeId, boolean isVideoCall) { - Log.d(TAG, "startCallActivity()"); + context.startActivity(getCallActivityIntent(context, serviceData, false)); + } - context.startActivity(getCallIntent(context, null, calleeId, isVideoCall, false)); + public static void onRinging(Context context, @NonNull DirectCall call) { + Log.i(BaseApplication.TAG, "[CallService] onRinging()"); + + ServiceData serviceData = new ServiceData(); + serviceData.isHeadsUpNotification = true; + serviceData.remoteNicknameOrUserId = UserInfoUtils.getNicknameOrUserId(call.getCallee()); + serviceData.callState = CallActivity.STATE.STATE_ACCEPTING; + serviceData.callId = call.getCallId(); + serviceData.isVideoCall = call.isVideoCall(); + serviceData.calleeIdToDial = null; + serviceData.doDial = false; + serviceData.doAccept = true; + serviceData.doLocalVideoStart = false; + + startService(context, serviceData); } - public static void startService(Context context, DirectCall call, boolean isHeadsUpNotification) { - Log.d(TAG, "startService()"); + private static void startService(Context context, ServiceData serviceData) { + Log.i(BaseApplication.TAG, "[CallService] startService()"); if (context != null) { Intent intent = new Intent(context, CallService.class); - intent.putExtra(EXTRA_REMOTE_NICKNAME_OR_USER_ID, UserInfoUtils.getNicknameOrUserId(call.getRemoteUser())); - intent.putExtra(EXTRA_CALL_ID, call.getCallId()); - intent.putExtra(EXTRA_CALLEE_ID, call.getCallee().getUserId()); - intent.putExtra(EXTRA_IS_VIDEO_CALL, call.isVideoCall()); - intent.putExtra(EXTRA_IS_HEADS_UP_NOTIFICATION, isHeadsUpNotification); - context.startService(intent); + intent.putExtra(EXTRA_IS_HEADS_UP_NOTIFICATION, serviceData.isHeadsUpNotification); + intent.putExtra(EXTRA_REMOTE_NICKNAME_OR_USER_ID, serviceData.remoteNicknameOrUserId); + intent.putExtra(EXTRA_CALL_STATE, serviceData.callState); + intent.putExtra(EXTRA_CALL_ID, serviceData.callId); + intent.putExtra(EXTRA_IS_VIDEO_CALL, serviceData.isVideoCall); + intent.putExtra(EXTRA_CALLEE_ID_TO_DIAL, serviceData.calleeIdToDial); + intent.putExtra(EXTRA_DO_DIAL, serviceData.doDial); + intent.putExtra(EXTRA_DO_ACCEPT, serviceData.doAccept); + intent.putExtra(EXTRA_DO_LOCAL_VIDEO_START, serviceData.doLocalVideoStart); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.startForegroundService(intent); + } else { + context.startService(intent); + } } } public static void stopService(Context context) { - Log.d(TAG, "stopService()"); + Log.i(BaseApplication.TAG, "[CallService] stopService()"); if (context != null) { Intent intent = new Intent(context, CallService.class); context.stopService(intent); } } + + public void updateNotification(@NonNull ServiceData serviceData) { + Log.i(BaseApplication.TAG, "[CallService] updateNotification(isHeadsUpNotification: " + serviceData.isHeadsUpNotification + ", remoteNicknameOrUserId: " + serviceData.remoteNicknameOrUserId + + ", callState: " + serviceData.callState + ", callId: " + serviceData.callId + ", isVideoCall: " + serviceData.isVideoCall + + ", calleeIdToDial: " + serviceData.calleeIdToDial + ", doDial: " + serviceData.doDial + ", doAccept: " + serviceData.doAccept + ", doLocalVideoStart: " + serviceData.doLocalVideoStart + ")"); + + mServiceData.set(serviceData); + startForeground(NOTIFICATION_ID, getNotification(mServiceData)); + } } diff --git a/app/src/main/java/com/sendbird/calls/quickstart/call/VideoCallActivity.java b/app/src/main/java/com/sendbird/calls/quickstart/call/VideoCallActivity.java index 388419f..28711b8 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/call/VideoCallActivity.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/call/VideoCallActivity.java @@ -1,6 +1,5 @@ package com.sendbird.calls.quickstart.call; -import android.Manifest; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.util.Log; @@ -16,6 +15,7 @@ import com.sendbird.calls.DirectCallUserRole; import com.sendbird.calls.SendBirdCall; import com.sendbird.calls.SendBirdVideoView; +import com.sendbird.calls.quickstart.BaseApplication; import com.sendbird.calls.quickstart.R; import com.sendbird.calls.quickstart.utils.ToastUtils; @@ -25,15 +25,7 @@ public class VideoCallActivity extends CallActivity { - private static final String TAG = "VideoCallActivity"; - - private static final String[] MANDATORY_PERMISSIONS = { - Manifest.permission.RECORD_AUDIO, - Manifest.permission.CAMERA - }; - - private boolean mIsVideoEnabled = true; - private boolean mIsMyVideoStopped; + private boolean mIsVideoEnabled; //+ Views private SendBirdVideoView mVideoViewFullScreen; @@ -49,15 +41,10 @@ protected int getLayoutResourceId() { return R.layout.activity_video_call; } - @Override - protected String[] getMandatoryPermissions() { - return MANDATORY_PERMISSIONS; - } - @Override protected void initViews() { super.initViews(); - Log.d(TAG, "initViews()"); + Log.i(BaseApplication.TAG, "[VideoCallActivity] initViews()"); mVideoViewFullScreen = findViewById(R.id.video_view_fullscreen); mViewConnectingVideoViewFullScreenFg = findViewById(R.id.view_connecting_video_view_fullscreen_fg); @@ -71,26 +58,49 @@ protected void initViews() { protected void setViews() { super.setViews(); + mVideoViewFullScreen.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT); + mVideoViewFullScreen.setZOrderMediaOverlay(false); + mVideoViewFullScreen.setEnableHardwareScaler(true); + + mVideoViewSmall.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT); + mVideoViewSmall.setZOrderMediaOverlay(true); + mVideoViewSmall.setEnableHardwareScaler(true); + + if (mDirectCall != null) { + if (mDirectCall.getMyRole() == DirectCallUserRole.CALLER && mState == STATE.STATE_OUTGOING) { + mDirectCall.setLocalVideoView(mVideoViewFullScreen); + mDirectCall.setRemoteVideoView(mVideoViewSmall); + } else { + mDirectCall.setLocalVideoView(mVideoViewSmall); + mDirectCall.setRemoteVideoView(mVideoViewFullScreen); + } + } + mImageViewCameraSwitch.setOnClickListener(view -> { if (mDirectCall != null) { mDirectCall.switchCamera(e -> { if (e != null) { - Log.d(TAG, "switchCamera(e: " + e.getMessage() + ")"); + Log.i(BaseApplication.TAG, "[VideoCallActivity] switchCamera(e: " + e.getMessage() + ")"); } }); } }); + if (mDirectCall != null && !mDoLocalVideoStart) { + mIsVideoEnabled = mDirectCall.isLocalVideoEnabled(); + } else { + mIsVideoEnabled = true; + } mImageViewVideoOff.setSelected(!mIsVideoEnabled); mImageViewVideoOff.setOnClickListener(view -> { if (mDirectCall != null) { if (mIsVideoEnabled) { - Log.d(TAG, "stopVideo()"); + Log.i(BaseApplication.TAG, "[VideoCallActivity] stopVideo()"); mDirectCall.stopVideo(); mIsVideoEnabled = false; mImageViewVideoOff.setSelected(true); } else { - Log.d(TAG, "startVideo()"); + Log.i(BaseApplication.TAG, "[VideoCallActivity] startVideo()"); mDirectCall.startVideo(); mIsVideoEnabled = true; mImageViewVideoOff.setSelected(false); @@ -119,8 +129,14 @@ protected void setViews() { }); } + protected void setLocalVideoSettings(DirectCall call) { + mIsVideoEnabled = call.isLocalVideoEnabled(); + Log.i(BaseApplication.TAG, "[VideoCallActivity] setLocalVideoSettings() => isLocalVideoEnabled(): " + mIsVideoEnabled); + mImageViewVideoOff.setSelected(!mIsVideoEnabled); + } + @Override - protected void audioDeviceChanged(DirectCall call, AudioDevice currentAudioDevice, Set availableAudioDevices) { + protected void setAudioDevice(AudioDevice currentAudioDevice, Set availableAudioDevices) { if (currentAudioDevice == AudioDevice.SPEAKERPHONE) { mImageViewBluetooth.setSelected(false); } else if (currentAudioDevice == AudioDevice.BLUETOOTH) { @@ -137,16 +153,6 @@ protected void audioDeviceChanged(DirectCall call, AudioDevice currentAudioDevic @Override protected void startCall(boolean amICallee) { CallOptions callOptions = new CallOptions(); - callOptions.setAudioEnabled(mIsAudioEnabled); - - mVideoViewFullScreen.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT); - mVideoViewFullScreen.setZOrderMediaOverlay(false); - mVideoViewFullScreen.setEnableHardwareScaler(true); - - mVideoViewSmall.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT); - mVideoViewSmall.setZOrderMediaOverlay(true); - mVideoViewSmall.setEnableHardwareScaler(true); - callOptions.setVideoEnabled(mIsVideoEnabled).setAudioEnabled(mIsAudioEnabled); if (amICallee) { @@ -156,15 +162,15 @@ protected void startCall(boolean amICallee) { } if (amICallee) { - Log.d(TAG, "accept()"); + Log.i(BaseApplication.TAG, "[VideoCallActivity] accept()"); if (mDirectCall != null) { mDirectCall.accept(new AcceptParams().setCallOptions(callOptions)); } } else { - Log.d(TAG, "dial()"); - mDirectCall = SendBirdCall.dial(new DialParams(mCalleeId).setVideoCall(mIsVideoCall).setCallOptions(callOptions), (call, e) -> { + Log.i(BaseApplication.TAG, "[VideoCallActivity] dial()"); + mDirectCall = SendBirdCall.dial(new DialParams(mCalleeIdToDial).setVideoCall(mIsVideoCall).setCallOptions(callOptions), (call, e) -> { if (e != null) { - Log.d(TAG, "dial() => e: " + e.getMessage()); + Log.i(BaseApplication.TAG, "[VideoCallActivity] dial() => e: " + e.getMessage()); if (e.getMessage() != null) { ToastUtils.showToast(mContext, e.getMessage()); } @@ -173,15 +179,11 @@ protected void startCall(boolean amICallee) { return; } - Log.d(TAG, "dial() => OK"); - if (mDirectCall != null) { - CallService.startService(mContext, mDirectCall, false); - } + Log.i(BaseApplication.TAG, "[VideoCallActivity] dial() => OK"); + updateCallService(); }); - if (mDirectCall != null) { - setListener(mDirectCall); - } + setListener(mDirectCall); } } @@ -194,7 +196,7 @@ protected boolean setState(STATE state, DirectCall call) { } switch (state) { - case STATE_INCOMING: { + case STATE_ACCEPTING: { mVideoViewFullScreen.setVisibility(View.GONE); mViewConnectingVideoViewFullScreenFg.setVisibility(View.GONE); mRelativeLayoutVideoViewSmall.setVisibility(View.GONE); @@ -221,13 +223,16 @@ protected boolean setState(STATE state, DirectCall call) { mLinearLayoutInfo.setVisibility(View.GONE); if (call != null && call.getMyRole() == DirectCallUserRole.CALLER) { - call.setRemoteVideoView(mVideoViewFullScreen); call.setLocalVideoView(mVideoViewSmall); + call.setRemoteVideoView(mVideoViewFullScreen); } break; } + case STATE_ENDING: case STATE_ENDED: { + mLinearLayoutInfo.setVisibility(View.VISIBLE); + mVideoViewFullScreen.setVisibility(View.GONE); mViewConnectingVideoViewFullScreenFg.setVisibility(View.GONE); mRelativeLayoutVideoViewSmall.setVisibility(View.GONE); @@ -239,24 +244,26 @@ protected boolean setState(STATE state, DirectCall call) { } @Override - protected void onResume() { - super.onResume(); - Log.d(TAG, "onResume()"); + protected void onStart() { + super.onStart(); + Log.i(BaseApplication.TAG, "[VideoCallActivity] onStart()"); - if (mDirectCall != null && mIsMyVideoStopped) { - mIsMyVideoStopped = false; + if (mDirectCall != null && mDoLocalVideoStart) { + mDoLocalVideoStart = false; + updateCallService(); mDirectCall.startVideo(); } } @Override - protected void onPause() { - super.onPause(); - Log.d(TAG, "onPause()"); + protected void onStop() { + super.onStop(); + Log.i(BaseApplication.TAG, "[VideoCallActivity] onStop()"); if (mDirectCall != null && mDirectCall.isLocalVideoEnabled()) { mDirectCall.stopVideo(); - mIsMyVideoStopped = true; + mDoLocalVideoStart = true; + updateCallService(); } } } diff --git a/app/src/main/java/com/sendbird/calls/quickstart/call/VoiceCallActivity.java b/app/src/main/java/com/sendbird/calls/quickstart/call/VoiceCallActivity.java index e7c93fc..b2e2c6b 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/call/VoiceCallActivity.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/call/VoiceCallActivity.java @@ -1,6 +1,5 @@ package com.sendbird.calls.quickstart.call; -import android.Manifest; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.util.Log; @@ -13,23 +12,17 @@ import com.sendbird.calls.DialParams; import com.sendbird.calls.DirectCall; import com.sendbird.calls.SendBirdCall; +import com.sendbird.calls.quickstart.BaseApplication; import com.sendbird.calls.quickstart.R; import com.sendbird.calls.quickstart.utils.TimeUtils; import com.sendbird.calls.quickstart.utils.ToastUtils; -import java.util.Locale; import java.util.Set; import java.util.Timer; import java.util.TimerTask; public class VoiceCallActivity extends CallActivity { - private static final String TAG = "VoiceCallActivity"; - - private static final String[] MANDATORY_PERMISSIONS = { - Manifest.permission.RECORD_AUDIO - }; - private Timer mCallDurationTimer; //+ Views @@ -41,15 +34,10 @@ protected int getLayoutResourceId() { return R.layout.activity_voice_call; } - @Override - protected String[] getMandatoryPermissions() { - return MANDATORY_PERMISSIONS; - } - @Override protected void initViews() { super.initViews(); - Log.d(TAG, "initViews()"); + Log.i(BaseApplication.TAG, "[VoiceCallActivity] initViews()"); mImageViewSpeakerphone = findViewById(R.id.image_view_speakerphone); } @@ -99,7 +87,7 @@ protected void setViews() { } @Override - protected void audioDeviceChanged(DirectCall call, AudioDevice currentAudioDevice, Set availableAudioDevices) { + protected void setAudioDevice(AudioDevice currentAudioDevice, Set availableAudioDevices) { if (currentAudioDevice == AudioDevice.SPEAKERPHONE) { mImageViewSpeakerphone.setSelected(true); mImageViewBluetooth.setSelected(false); @@ -129,15 +117,15 @@ protected void startCall(boolean amICallee) { callOptions.setAudioEnabled(mIsAudioEnabled); if (amICallee) { - Log.d(TAG, "accept()"); + Log.i(BaseApplication.TAG, "[VoiceCallActivity] accept()"); if (mDirectCall != null) { mDirectCall.accept(new AcceptParams().setCallOptions(callOptions)); } } else { - Log.d(TAG, "dial()"); - mDirectCall = SendBirdCall.dial(new DialParams(mCalleeId).setVideoCall(mIsVideoCall).setCallOptions(callOptions), (call, e) -> { + Log.i(BaseApplication.TAG, "[VoiceCallActivity] dial()"); + mDirectCall = SendBirdCall.dial(new DialParams(mCalleeIdToDial).setVideoCall(mIsVideoCall).setCallOptions(callOptions), (call, e) -> { if (e != null) { - Log.d(TAG, "dial() => e: " + e.getMessage()); + Log.i(BaseApplication.TAG, "[VoiceCallActivity] dial() => e: " + e.getMessage()); if (e.getMessage() != null) { ToastUtils.showToast(mContext, e.getMessage()); } @@ -146,15 +134,11 @@ protected void startCall(boolean amICallee) { return; } - Log.d(TAG, "dial() => OK"); - if (mDirectCall != null) { - CallService.startService(mContext, mDirectCall, false); - } + Log.i(BaseApplication.TAG, "[VoiceCallActivity] dial() => OK"); + updateCallService(); }); - if (mDirectCall != null) { - setListener(mDirectCall); - } + setListener(mDirectCall); } } @@ -212,7 +196,7 @@ private void cancelCallDurationTimer() { @Override protected void onDestroy() { super.onDestroy(); - Log.d(TAG, "onDestroy()"); + Log.i(BaseApplication.TAG, "[VoiceCallActivity] onDestroy()"); cancelCallDurationTimer(); } } diff --git a/app/src/main/java/com/sendbird/calls/quickstart/fcm/MyFirebaseMessagingService.java b/app/src/main/java/com/sendbird/calls/quickstart/fcm/MyFirebaseMessagingService.java index 757c2e1..f6079ea 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/fcm/MyFirebaseMessagingService.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/fcm/MyFirebaseMessagingService.java @@ -7,36 +7,27 @@ import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; import com.sendbird.calls.SendBirdCall; +import com.sendbird.calls.quickstart.BaseApplication; import com.sendbird.calls.quickstart.utils.PrefUtils; import com.sendbird.calls.quickstart.utils.PushUtils; public class MyFirebaseMessagingService extends FirebaseMessagingService { - private static final String TAG = "MyFirebaseMessagingServ"; - @Override public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { if (SendBirdCall.handleFirebaseMessageData(remoteMessage.getData())) { - Log.d(TAG, "[SendBirdCall Message] onMessageReceived() => " + remoteMessage.getData().toString()); - } else { - Log.d(TAG, "onMessageReceived() => From: " + remoteMessage.getFrom()); - if (remoteMessage.getData().size() > 0) { - Log.d(TAG, "onMessageReceived() => Data: " + remoteMessage.getData().toString()); - } - if (remoteMessage.getNotification() != null) { - Log.d(TAG, "onMessageReceived() => Notification Body: " + remoteMessage.getNotification().getBody()); - } + Log.i(BaseApplication.TAG, "[MyFirebaseMessagingService] onMessageReceived() => " + remoteMessage.getData().toString()); } } @Override public void onNewToken(@NonNull String token) { - Log.d(TAG, "onNewToken(token: " + token + ")"); + Log.i(BaseApplication.TAG, "[MyFirebaseMessagingService] onNewToken(token: " + token + ")"); if (SendBirdCall.getCurrentUser() != null) { PushUtils.registerPushToken(getApplicationContext(), token, e -> { if (e != null) { - Log.d(TAG, "registerPushTokenForCurrentUser() => e: " + e.getMessage()); + Log.i(BaseApplication.TAG, "[MyFirebaseMessagingService] registerPushTokenForCurrentUser() => e: " + e.getMessage()); } }); } else { diff --git a/app/src/main/java/com/sendbird/calls/quickstart/main/DialFragment.java b/app/src/main/java/com/sendbird/calls/quickstart/main/DialFragment.java index 79df238..1e82290 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/main/DialFragment.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/main/DialFragment.java @@ -84,7 +84,7 @@ public void afterTextChanged(Editable editable) { mImageViewVideoCall.setOnClickListener(view1 -> { String calleeId = (mTextInputEditTextUserId.getText() != null ? mTextInputEditTextUserId.getText().toString() : ""); if (!TextUtils.isEmpty(calleeId)) { - CallService.startCallActivity(getContext(), calleeId, true); + CallService.dial(getContext(), calleeId, true); PrefUtils.setCalleeId(getContext(), calleeId); } }); @@ -92,7 +92,7 @@ public void afterTextChanged(Editable editable) { mImageViewVoiceCall.setOnClickListener(view1 -> { String calleeId = (mTextInputEditTextUserId.getText() != null ? mTextInputEditTextUserId.getText().toString() : ""); if (!TextUtils.isEmpty(calleeId)) { - CallService.startCallActivity(getContext(), calleeId, false); + CallService.dial(getContext(), calleeId, false); PrefUtils.setCalleeId(getContext(), calleeId); } }); diff --git a/app/src/main/java/com/sendbird/calls/quickstart/main/HistoryRecyclerViewAdapter.java b/app/src/main/java/com/sendbird/calls/quickstart/main/HistoryRecyclerViewAdapter.java index d293aa1..d9bf285 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/main/HistoryRecyclerViewAdapter.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/main/HistoryRecyclerViewAdapter.java @@ -89,11 +89,11 @@ public void onBindViewHolder(@NonNull HistoryViewHolder holder, int position) { holder.textViewStartAt.setText(TimeUtils.getDateString(callLog.getStartedAt())); holder.imageViewVideoCall.setOnClickListener(view -> { - CallService.startCallActivity(mContext, user.getUserId(), true); + CallService.dial(mContext, user.getUserId(), true); }); holder.imageViewVoiceCall.setOnClickListener(view -> { - CallService.startCallActivity(mContext, user.getUserId(), false); + CallService.dial(mContext, user.getUserId(), false); }); } diff --git a/app/src/main/java/com/sendbird/calls/quickstart/main/MainActivity.java b/app/src/main/java/com/sendbird/calls/quickstart/main/MainActivity.java index 7094fa2..048cf50 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/main/MainActivity.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/main/MainActivity.java @@ -1,13 +1,18 @@ package com.sendbird.calls.quickstart.main; +import android.Manifest; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.os.Build; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.widget.LinearLayout; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.viewpager.widget.ViewPager; @@ -15,15 +20,24 @@ import com.google.android.material.tabs.TabLayout; import com.sendbird.calls.DirectCallLog; import com.sendbird.calls.SendBirdCall; +import com.sendbird.calls.quickstart.BaseApplication; import com.sendbird.calls.quickstart.R; import com.sendbird.calls.quickstart.utils.BroadcastUtils; +import com.sendbird.calls.quickstart.utils.ToastUtils; import com.sendbird.calls.quickstart.utils.UserInfoUtils; +import java.util.ArrayList; + public class MainActivity extends AppCompatActivity { - private static final String TAG = "MainActivity"; + private static final String[] MANDATORY_PERMISSIONS = { + Manifest.permission.RECORD_AUDIO, // for VoiceCall and VideoCall + Manifest.permission.CAMERA // for VideoCall + }; + private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 1; private Context mContext; + private LinearLayout mLinearLayoutToolbar; private MainPagerAdapter mMainPagerAdapter; private BroadcastReceiver mReceiver; @@ -38,6 +52,7 @@ protected void onCreate(Bundle savedInstanceState) { initViews(); registerReceiver(); + checkPermissions(); } @Override @@ -110,6 +125,8 @@ public void onPageScrollStateChanged(int state) { } private void registerReceiver() { + Log.i(BaseApplication.TAG, "[MainActivity] registerReceiver()"); + if (mReceiver != null) { return; } @@ -117,6 +134,8 @@ private void registerReceiver() { mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { + Log.i(BaseApplication.TAG, "[MainActivity] onReceive()"); + DirectCallLog callLog = (DirectCallLog)intent.getSerializableExtra(BroadcastUtils.INTENT_EXTRA_CALL_LOG); if (callLog != null) { HistoryFragment historyFragment = (HistoryFragment) mMainPagerAdapter.getItem(1); @@ -131,9 +150,43 @@ public void onReceive(Context context, Intent intent) { } private void unregisterReceiver() { + Log.i(BaseApplication.TAG, "[MainActivity] unregisterReceiver()"); + if (mReceiver != null) { unregisterReceiver(mReceiver); mReceiver = null; } } + + private void checkPermissions() { + ArrayList deniedPermissions = new ArrayList<>(); + for (String permission : MANDATORY_PERMISSIONS) { + if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { + deniedPermissions.add(permission); + } + } + + if (deniedPermissions.size() > 0) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + requestPermissions(deniedPermissions.toArray(new String[0]), REQUEST_PERMISSIONS_REQUEST_CODE); + } else { + ToastUtils.showToast(mContext, "Permission denied."); + } + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) { + boolean allowed = true; + + for (int result : grantResults) { + allowed = allowed && (result == PackageManager.PERMISSION_GRANTED); + } + + if (!allowed) { + ToastUtils.showToast(mContext, "Permission denied."); + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/sendbird/calls/quickstart/utils/ActivityUtils.java b/app/src/main/java/com/sendbird/calls/quickstart/utils/ActivityUtils.java index 425925b..400dd18 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/utils/ActivityUtils.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/utils/ActivityUtils.java @@ -7,18 +7,17 @@ import androidx.annotation.NonNull; import com.sendbird.calls.quickstart.AuthenticateActivity; +import com.sendbird.calls.quickstart.BaseApplication; import com.sendbird.calls.quickstart.SignInManuallyActivity; import com.sendbird.calls.quickstart.main.ApplicationInformationActivity; import com.sendbird.calls.quickstart.main.MainActivity; public class ActivityUtils { - private static final String TAG = "ActivityUtils"; - public static final int START_SIGN_IN_MANUALLY_ACTIVITY_REQUEST_CODE = 1; public static void startAuthenticateActivityAndFinish(@NonNull Activity activity) { - Log.d(TAG, "startAuthenticateActivityAndFinish()"); + Log.i(BaseApplication.TAG, "[ActivityUtils] startAuthenticateActivityAndFinish()"); Intent intent = new Intent(activity, AuthenticateActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); @@ -27,7 +26,7 @@ public static void startAuthenticateActivityAndFinish(@NonNull Activity activity } public static void startSignInManuallyActivityForResult(@NonNull Activity activity) { - Log.d(TAG, "startSignInManuallyActivityAndFinish()"); + Log.i(BaseApplication.TAG, "[ActivityUtils] startSignInManuallyActivityAndFinish()"); Intent intent = new Intent(activity, SignInManuallyActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); @@ -35,7 +34,7 @@ public static void startSignInManuallyActivityForResult(@NonNull Activity activi } public static void startMainActivityAndFinish(@NonNull Activity activity) { - Log.d(TAG, "startMainActivityAndFinish()"); + Log.i(BaseApplication.TAG, "[ActivityUtils] startMainActivityAndFinish()"); Intent intent = new Intent(activity, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); @@ -44,7 +43,7 @@ public static void startMainActivityAndFinish(@NonNull Activity activity) { } public static void startApplicationInformationActivity(@NonNull Activity activity) { - Log.d(TAG, "startApplicationInformationActivity()"); + Log.i(BaseApplication.TAG, "[ActivityUtils] startApplicationInformationActivity()"); Intent intent = new Intent(activity, ApplicationInformationActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); diff --git a/app/src/main/java/com/sendbird/calls/quickstart/utils/AuthenticationUtils.java b/app/src/main/java/com/sendbird/calls/quickstart/utils/AuthenticationUtils.java index aa5a15e..75b0f9c 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/utils/AuthenticationUtils.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/utils/AuthenticationUtils.java @@ -7,21 +7,20 @@ import com.sendbird.calls.AuthenticateParams; import com.sendbird.calls.SendBirdCall; import com.sendbird.calls.SendBirdException; +import com.sendbird.calls.quickstart.BaseApplication; import com.sendbird.calls.quickstart.R; public class AuthenticationUtils { - private static final String TAG = "AuthenticationUtils"; - public interface AuthenticateHandler { void onResult(boolean isSuccess); } public static void authenticate(Context context, String userId, String accessToken, AuthenticateHandler handler) { - Log.d(TAG, "authenticate()"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] authenticate()"); if (userId == null) { - Log.d(TAG, "authenticate() => Failed (userId == null)"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] authenticate() => Failed (userId == null)"); if (handler != null) { handler.onResult(false); } @@ -30,17 +29,17 @@ public static void authenticate(Context context, String userId, String accessTok PushUtils.getPushToken(context, (pushToken, e) -> { if (e != null) { - Log.d(TAG, "authenticate() => Failed (e: " + e.getMessage() + ")"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] authenticate() => Failed (e: " + e.getMessage() + ")"); if (handler != null) { handler.onResult(false); } return; } - Log.d(TAG, "authenticate() => authenticate()"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] authenticate() => authenticate()"); SendBirdCall.authenticate(new AuthenticateParams(userId).setAccessToken(accessToken), (user, e1) -> { if (e1 != null) { - Log.d(TAG, "authenticate() => authenticate() => Failed (e1: " + e1.getMessage() + ")"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] authenticate() => authenticate() => Failed (e1: " + e1.getMessage() + ")"); showToastErrorMessage(context, e1); if (handler != null) { @@ -49,10 +48,10 @@ public static void authenticate(Context context, String userId, String accessTok return; } - Log.d(TAG, "authenticate() => registerPushToken()"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] authenticate() => registerPushToken()"); SendBirdCall.registerPushToken(pushToken, false, e2 -> { if (e2 != null) { - Log.d(TAG, "authenticate() => registerPushToken() => Failed (e2: " + e2.getMessage() + ")"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] authenticate() => registerPushToken() => Failed (e2: " + e2.getMessage() + ")"); showToastErrorMessage(context, e2); if (handler != null) { @@ -66,7 +65,7 @@ public static void authenticate(Context context, String userId, String accessTok PrefUtils.setAccessToken(context, accessToken); PrefUtils.setPushToken(context, pushToken); - Log.d(TAG, "authenticate() => authenticate() => OK"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] authenticate() => authenticate() => OK"); if (handler != null) { handler.onResult(true); } @@ -80,13 +79,13 @@ public interface DeauthenticateHandler { } public static void deauthenticate(Context context, DeauthenticateHandler handler) { - Log.d(TAG, "deauthenticate()"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] deauthenticate()"); String pushToken = PrefUtils.getPushToken(context); if (!TextUtils.isEmpty(pushToken)) { SendBirdCall.unregisterPushToken(pushToken, e -> { if (e != null) { - Log.d(TAG, "unregisterPushToken() => Failed (e: " + e.getMessage() + ")"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] unregisterPushToken() => Failed (e: " + e.getMessage() + ")"); showToastErrorMessage(context, e); } @@ -100,10 +99,10 @@ public static void deauthenticate(Context context, DeauthenticateHandler handler private static void doDeauthenticate(Context context, DeauthenticateHandler handler) { SendBirdCall.deauthenticate(e -> { if (e != null) { - Log.d(TAG, "deauthenticate() => Failed (e: " + e.getMessage() + ")"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] deauthenticate() => Failed (e: " + e.getMessage() + ")"); showToastErrorMessage(context, e); } else { - Log.d(TAG, "deauthenticate() => OK"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] deauthenticate() => OK"); } PrefUtils.setUserId(context, null); @@ -122,10 +121,10 @@ public interface AutoAuthenticateHandler { } public static void autoAuthenticate(Context context, AutoAuthenticateHandler handler) { - Log.d(TAG, "autoAuthenticate()"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] autoAuthenticate()"); if (SendBirdCall.getCurrentUser() != null) { - Log.d(TAG, "autoAuthenticate() => OK (SendBirdCall.getCurrentUser() != null)"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] autoAuthenticate() => OK (SendBirdCall.getCurrentUser() != null)"); if (handler != null) { handler.onResult(SendBirdCall.getCurrentUser().getUserId()); } @@ -136,10 +135,10 @@ public static void autoAuthenticate(Context context, AutoAuthenticateHandler han String accessToken = PrefUtils.getAccessToken(context); String pushToken = PrefUtils.getPushToken(context); if (!TextUtils.isEmpty(userId) && !TextUtils.isEmpty(pushToken)) { - Log.d(TAG, "autoAuthenticate() => authenticate()"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] autoAuthenticate() => authenticate()"); SendBirdCall.authenticate(new AuthenticateParams(userId).setAccessToken(accessToken), (user, e) -> { if (e != null) { - Log.d(TAG, "autoAuthenticate() => authenticate() => Failed (e: " + e.getMessage() + ")"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] autoAuthenticate() => authenticate() => Failed (e: " + e.getMessage() + ")"); showToastErrorMessage(context, e); if (handler != null) { @@ -148,10 +147,10 @@ public static void autoAuthenticate(Context context, AutoAuthenticateHandler han return; } - Log.d(TAG, "autoAuthenticate() => registerPushToken()"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] autoAuthenticate() => registerPushToken()"); SendBirdCall.registerPushToken(pushToken, false, e1 -> { if (e1 != null) { - Log.d(TAG, "autoAuthenticate() => registerPushToken() => Failed (e1: " + e1.getMessage() + ")"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] autoAuthenticate() => registerPushToken() => Failed (e1: " + e1.getMessage() + ")"); showToastErrorMessage(context, e1); if (handler != null) { @@ -160,14 +159,14 @@ public static void autoAuthenticate(Context context, AutoAuthenticateHandler han return; } - Log.d(TAG, "autoAuthenticate() => authenticate() => OK (Authenticated)"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] autoAuthenticate() => authenticate() => OK (Authenticated)"); if (handler != null) { handler.onResult(userId); } }); }); } else { - Log.d(TAG, "autoAuthenticate() => Failed (No userId and pushToken)"); + Log.i(BaseApplication.TAG, "[AuthenticationUtils] autoAuthenticate() => Failed (No userId and pushToken)"); if (handler != null) { handler.onResult(null); } @@ -176,8 +175,8 @@ public static void autoAuthenticate(Context context, AutoAuthenticateHandler han private static void showToastErrorMessage(Context context, SendBirdException e) { if (context != null) { - if (e.getCode() == 1800200) { - ToastUtils.showToast(context, context.getString(R.string.calls_invalid_notifications_not_active_for_qrcode)); + if (e.getCode() == 400111) { + ToastUtils.showToast(context, context.getString(R.string.calls_invalid_notifications_setting_in_dashboard)); } else { ToastUtils.showToast(context, e.getMessage()); } diff --git a/app/src/main/java/com/sendbird/calls/quickstart/utils/BroadcastUtils.java b/app/src/main/java/com/sendbird/calls/quickstart/utils/BroadcastUtils.java index 6164777..932af32 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/utils/BroadcastUtils.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/utils/BroadcastUtils.java @@ -5,17 +5,16 @@ import android.util.Log; import com.sendbird.calls.DirectCallLog; +import com.sendbird.calls.quickstart.BaseApplication; public class BroadcastUtils { - private static final String TAG = "BroadcastUtils"; - public static final String INTENT_ACTION_ADD_CALL_LOG = "com.sendbird.calls.quickstart.intent.action.ADD_CALL_LOG"; public static final String INTENT_EXTRA_CALL_LOG = "call_log"; public static void sendCallLogBroadcast(Context context, DirectCallLog callLog) { if (context != null && callLog != null) { - Log.d(TAG, "sendCallLogBroadcast()"); + Log.i(BaseApplication.TAG, "[BroadcastUtils] sendCallLogBroadcast()"); Intent intent = new Intent(INTENT_ACTION_ADD_CALL_LOG); intent.putExtra(INTENT_EXTRA_CALL_LOG, callLog); diff --git a/app/src/main/java/com/sendbird/calls/quickstart/utils/PushUtils.java b/app/src/main/java/com/sendbird/calls/quickstart/utils/PushUtils.java index 446b6b4..1525a15 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/utils/PushUtils.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/utils/PushUtils.java @@ -7,23 +7,22 @@ import com.google.firebase.iid.FirebaseInstanceId; import com.sendbird.calls.SendBirdCall; import com.sendbird.calls.SendBirdException; +import com.sendbird.calls.quickstart.BaseApplication; public class PushUtils { - private static final String TAG = "PushUtils"; - public interface GetPushTokenHandler { void onResult(String token, SendBirdException e); } public static void getPushToken(Context context, final GetPushTokenHandler handler) { - Log.d(TAG, "getPushToken()"); + Log.i(BaseApplication.TAG, "[PushUtils] getPushToken()"); String savedToken = PrefUtils.getPushToken(context); if (TextUtils.isEmpty(savedToken)) { FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(task -> { if (!task.isSuccessful()) { - Log.d(TAG, "getPushToken() => getInstanceId failed", task.getException()); + Log.i(BaseApplication.TAG, "[PushUtils] getPushToken() => getInstanceId failed", task.getException()); if (handler != null) { handler.onResult(null, new SendBirdException((task.getException() != null ? task.getException().getMessage() : ""))); } @@ -31,13 +30,13 @@ public static void getPushToken(Context context, final GetPushTokenHandler handl } String pushToken = (task.getResult() != null ? task.getResult().getToken() : ""); - Log.d(TAG, "getPushToken() => pushToken: " + pushToken); + Log.i(BaseApplication.TAG, "[PushUtils] getPushToken() => pushToken: " + pushToken); if (handler != null) { handler.onResult(pushToken, null); } }); } else { - Log.d(TAG, "savedToken: " + savedToken); + Log.i(BaseApplication.TAG, "[PushUtils] savedToken: " + savedToken); if (handler != null) { handler.onResult(savedToken, null); } @@ -49,11 +48,11 @@ public interface PushTokenHandler { } public static void registerPushToken(Context context, String pushToken, PushTokenHandler handler) { - Log.d(TAG, "registerPushToken(pushToken: " + pushToken + ")"); + Log.i(BaseApplication.TAG, "[PushUtils] registerPushToken(pushToken: " + pushToken + ")"); SendBirdCall.registerPushToken(pushToken, false, e -> { if (e != null) { - Log.d(TAG, "registerPushToken() => e: " + e.getMessage()); + Log.i(BaseApplication.TAG, "[PushUtils] registerPushToken() => e: " + e.getMessage()); PrefUtils.setPushToken(context, pushToken); if (handler != null) { @@ -62,7 +61,7 @@ public static void registerPushToken(Context context, String pushToken, PushToke return; } - Log.d(TAG, "registerPushToken() => OK"); + Log.i(BaseApplication.TAG, "[PushUtils] registerPushToken() => OK"); PrefUtils.setPushToken(context, pushToken); if (handler != null) { diff --git a/app/src/main/java/com/sendbird/calls/quickstart/utils/QRCodeUtils.java b/app/src/main/java/com/sendbird/calls/quickstart/utils/QRCodeUtils.java index 89e9362..2a47dbd 100644 --- a/app/src/main/java/com/sendbird/calls/quickstart/utils/QRCodeUtils.java +++ b/app/src/main/java/com/sendbird/calls/quickstart/utils/QRCodeUtils.java @@ -61,7 +61,7 @@ public static boolean onActivityResult(Activity activity, int requestCode, int r }); } else { if (resultCode != Activity.RESULT_CANCELED) { - ToastUtils.showToast(activity, activity.getString(R.string.calls_invalid_for_qrcode)); + ToastUtils.showToast(activity, activity.getString(R.string.calls_invalid_qrcode)); } if (handler != null) { diff --git a/app/src/main/res/layout/activity_video_call.xml b/app/src/main/res/layout/activity_video_call.xml index 4ed1c62..a28dbb6 100644 --- a/app/src/main/res/layout/activity_video_call.xml +++ b/app/src/main/res/layout/activity_video_call.xml @@ -121,14 +121,6 @@ android:background="@drawable/btn_call_end" android:layout_centerHorizontal="true" /> - - - - Voice calling from %s Video calling from %s - END - CALL + Accept + Decline + End Make a call Enter the user ID of the user you wish to call, then press one of the video or voice call buttons @@ -50,7 +51,7 @@ Dial failed Other device accepted - Mobile sign-in is not enabled. Please first enable notifications on the Sendbird Dashboard. - This QR code is not valid. Please generate and scan a user-specific QR code in Calls studio. + Mobile sign-in is not enabled. Please first enable notifications on the Sendbird Dashboard. + This QR code is not valid. Please generate and scan a user-specific QR code in Calls studio.