diff --git a/sample-videochat-java/app/build.gradle b/sample-videochat-java/app/build.gradle index 3d338fdcc..c6a5345a1 100755 --- a/sample-videochat-java/app/build.gradle +++ b/sample-videochat-java/app/build.gradle @@ -20,26 +20,26 @@ android { compileSdkVersion 31 buildToolsVersion "31.0.0" - flavorDimensions dimensionDefault + flavorDimensions "default" defaultConfig { applicationId "com.quickblox.sample.videochat.java" minSdkVersion 21 targetSdkVersion 31 - versionCode 405000 - versionName '4.0.5' + versionCode 410000 + versionName '4.1.0' multiDexEnabled true } productFlavors { dev { - dimension dimensionDefault + dimension "default" buildConfigField('boolean', "IS_QA", "false") buildConfigField("int", "VERSION_QA_CODE", versionQACode.toString()) } qa { - dimension dimensionDefault + dimension "default" buildConfigField("boolean", "IS_QA", "true") buildConfigField("int", "VERSION_QA_CODE", versionQACode.toString()) } @@ -83,14 +83,14 @@ android { } dependencies { - implementation "com.quickblox:quickblox-android-sdk-videochat-webrtc:$qbSdkVersion" - implementation "com.quickblox:quickblox-android-sdk-messages:$qbSdkVersion" + implementation 'com.quickblox:quickblox-android-sdk-videochat-webrtc:3.10.1' + implementation 'com.quickblox:quickblox-android-sdk-messages:3.10.1' - implementation "com.google.firebase:firebase-core:$firebaseCoreVersion" - implementation "com.navercorp.pulltorefresh:library:$pullToRefreshVersion@aar" + implementation 'com.google.firebase:firebase-core:21.1.0' + implementation 'com.navercorp.pulltorefresh:library:3.2.3@aar' - implementation "com.google.android.material:material:$materialVersion" - implementation "com.github.johnkil.android-robototextview:robototextview:$robotoTextViewVersion" + implementation 'com.google.android.material:material:1.6.1' + implementation 'com.github.johnkil.android-robototextview:robototextview:4.0.0' } apply from: "../artifacts.gradle" diff --git a/sample-videochat-java/app/proguard-rules.pro b/sample-videochat-java/app/proguard-rules.pro index 79cb26c49..2f1f26c83 100644 --- a/sample-videochat-java/app/proguard-rules.pro +++ b/sample-videochat-java/app/proguard-rules.pro @@ -41,4 +41,7 @@ -keep class org.webrtc.** { *; } #google gms --keep class com.google.android.gms.** { *; } \ No newline at end of file +-keep class com.google.android.gms.** { *; } + +#json +-keep class org.json.** { *; } \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/AndroidManifest.xml b/sample-videochat-java/app/src/main/AndroidManifest.xml index efe74e078..9e74c6b56 100755 --- a/sample-videochat-java/app/src/main/AndroidManifest.xml +++ b/sample-videochat-java/app/src/main/AndroidManifest.xml @@ -62,11 +62,6 @@ android:screenOrientation="portrait" android:theme="@style/BaseAppTheme" /> - - diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/App.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/App.java index 9c2aa8ca3..e21095f08 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/App.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/App.java @@ -6,7 +6,7 @@ import com.quickblox.sample.videochat.java.util.QBResRequestExecutor; public class App extends Application { - //App credentials + // аpp credentials private static final String APPLICATION_ID = ""; private static final String AUTH_KEY = ""; private static final String AUTH_SECRET = ""; @@ -35,7 +35,7 @@ private void initCredentials() { QBSettings.getInstance().init(getApplicationContext(), APPLICATION_ID, AUTH_KEY, AUTH_SECRET); QBSettings.getInstance().setAccountKey(ACCOUNT_KEY); - // Uncomment and put your Api and Chat servers endpoints if you want to point the sample + // uncomment and put your Api and Chat servers endpoints if you want to point the sample // against your own server. // // QBSettings.getInstance().setEndpoints("https://your_api_endpoint.com", "your_chat_endpoint", ServiceZone.PRODUCTION); diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/AppInfoActivity.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/AppInfoActivity.java index a7841a10a..e081c7b4b 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/AppInfoActivity.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/AppInfoActivity.java @@ -14,7 +14,6 @@ import com.quickblox.sample.videochat.java.BuildConfig; import com.quickblox.sample.videochat.java.R; - public class AppInfoActivity extends BaseActivity { private TextView appVersionTextView; @@ -68,9 +67,9 @@ public void fillUI() { if (BuildConfig.IS_QA) { String appVersion = BuildConfig.VERSION_NAME; String versionQACode = String.valueOf(BuildConfig.VERSION_QA_CODE); - String qaVersion = appVersion + "." + versionQACode; + String qaVersion = appVersion + "(" + versionQACode + ")"; Spannable spannable = new SpannableString(qaVersion); - spannable.setSpan(new ForegroundColorSpan(Color.RED), appVersion.length() + 1, + spannable.setSpan(new ForegroundColorSpan(Color.RED), appVersion.length(), qaVersion.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); appQAVersionTextView.setText(spannable, TextView.BufferType.SPANNABLE); appQAVersionTextView.setVisibility(View.VISIBLE); diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/BaseActivity.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/BaseActivity.java index f35ba1a10..6b2ff9468 100755 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/BaseActivity.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/BaseActivity.java @@ -4,26 +4,21 @@ import android.content.DialogInterface; import android.content.pm.PackageManager; import android.os.Bundle; -import android.os.Environment; -import android.os.PowerManager; import android.view.KeyEvent; import android.view.MenuItem; import android.view.View; +import androidx.annotation.StringRes; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.ContextCompat; + import com.quickblox.sample.videochat.java.App; import com.quickblox.sample.videochat.java.R; import com.quickblox.sample.videochat.java.util.QBResRequestExecutor; -import com.quickblox.sample.videochat.java.utils.Consts; import com.quickblox.sample.videochat.java.utils.ErrorUtils; import com.quickblox.sample.videochat.java.utils.SharedPrefsHelper; -import java.io.File; - -import androidx.annotation.StringRes; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.content.ContextCompat; - /** * QuickBlox team */ @@ -45,8 +40,8 @@ protected void onCreate(Bundle savedInstanceState) { public void initDefaultActionBar() { String currentUserFullName = ""; - if (sharedPrefsHelper.getQbUser() != null) { - currentUserFullName = sharedPrefsHelper.getQbUser().getFullName(); + if (sharedPrefsHelper.getUser() != null) { + currentUserFullName = sharedPrefsHelper.getUser().getFullName(); } setActionBarTitle(""); diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/CallActivity.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/CallActivity.java index 4a8b526eb..510f28143 100755 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/CallActivity.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/CallActivity.java @@ -1,31 +1,30 @@ package com.quickblox.sample.videochat.java.activities; import android.app.Activity; -import android.app.PendingIntent; +import android.app.KeyguardManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.content.SharedPreferences; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.SystemClock; -import android.preference.PreferenceManager; import android.provider.Settings; import android.util.Log; import android.view.View; import android.view.ViewGroup; +import android.view.WindowManager; import android.widget.LinearLayout; import android.widget.TextView; import androidx.fragment.app.Fragment; -import com.quickblox.chat.QBChatService; import com.quickblox.sample.videochat.java.R; -import com.quickblox.sample.videochat.java.db.QbUsersDbManager; +import com.quickblox.sample.videochat.java.db.UsersDbManager; import com.quickblox.sample.videochat.java.fragments.AudioConversationFragment; import com.quickblox.sample.videochat.java.fragments.BaseConversationFragment; import com.quickblox.sample.videochat.java.fragments.ConversationFragmentCallback; @@ -34,13 +33,12 @@ import com.quickblox.sample.videochat.java.fragments.ScreenShareFragment; import com.quickblox.sample.videochat.java.fragments.VideoConversationFragment; import com.quickblox.sample.videochat.java.services.CallService; -import com.quickblox.sample.videochat.java.services.LoginService; import com.quickblox.sample.videochat.java.utils.Consts; import com.quickblox.sample.videochat.java.utils.ErrorUtils; import com.quickblox.sample.videochat.java.utils.FragmentExecuotr; import com.quickblox.sample.videochat.java.utils.PermissionsChecker; import com.quickblox.sample.videochat.java.utils.QBEntityCallbackImpl; -import com.quickblox.sample.videochat.java.utils.SettingsUtil; +import com.quickblox.sample.videochat.java.utils.SettingsManager; import com.quickblox.sample.videochat.java.utils.SharedPrefsHelper; import com.quickblox.sample.videochat.java.utils.ToastUtils; import com.quickblox.sample.videochat.java.utils.UsersUtils; @@ -80,18 +78,18 @@ public class CallActivity extends BaseActivity implements IncomeCallFragmentCall public static final String INCOME_CALL_FRAGMENT = "income_call_fragment"; public static final int REQUEST_PERMISSION_SETTING = 545; - private ArrayList currentCallStateCallbackList = new ArrayList<>(); - private QbUsersDbManager dbManager = QbUsersDbManager.getInstance(this); + private final ArrayList currentCallStateCallbackList = new ArrayList<>(); + private final UsersDbManager dbManager = UsersDbManager.getInstance(); private Handler showIncomingCallWindowTaskHandler; private ConnectionListenerImpl connectionListener; private ServiceConnection callServiceConnection; private Runnable showIncomingCallWindowTask; private boolean isInComingCall = false; - private List opponentsIdsList; - private SharedPreferences sharedPref; + private List opponentIds; private boolean isVideoCall = false; private PermissionsChecker checker; private CallService callService; + private LinearLayout connectionView; public static void start(Context context, boolean isIncomingCall) { Intent intent = new Intent(context, CallActivity.class); @@ -105,19 +103,58 @@ public static void start(Context context, boolean isIncomingCall) { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + allowOnLockScreen(); setContentView(R.layout.activity_main); checker = new PermissionsChecker(this); + connectionView = (LinearLayout) View.inflate(CallActivity.this, R.layout.connection_popup, null); + } + + @Override + protected void onResume() { + super.onResume(); + bindCallService(); + } + + @Override + protected void onPause() { + super.onPause(); + unbindService(callServiceConnection); + if (callService != null) { + removeListeners(); + } + } + + @Override + public void finish() { + CallService.stop(this); + OpponentsActivity.start(this); + super.finish(); + } + + @Override + public void onBackPressed() { + // to prevent returning from Call Fragment + } + + private void allowOnLockScreen() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { + setShowWhenLocked(true); + setTurnScreenOn(true); + KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); + keyguardManager.requestDismissKeyguard(this, null); + } else { + this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | + WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | + WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); + } } private void initScreen() { callService.setCallTimerCallback(new CallTimerCallback()); isVideoCall = callService.isVideoCall(); + opponentIds = callService.getOpponentIds(); - opponentsIdsList = callService.getOpponents(); - PreferenceManager.setDefaultValues(this, R.xml.preferences, false); - sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - - initSettingsStrategy(); + SettingsManager.applySettings(); addListeners(); if (getIntent() != null && getIntent().getExtras() != null) { @@ -167,15 +204,7 @@ protected void onActivityResult(int requestCode, int resultCode, final Intent da super.onActivityResult(requestCode, resultCode, data); Log.i(TAG, "onActivityResult requestCode=" + requestCode + ", resultCode= " + resultCode); if (resultCode == Consts.EXTRA_LOGIN_RESULT_CODE) { - if (data != null) { - boolean isLoginSuccess = data.getBooleanExtra(Consts.EXTRA_LOGIN_RESULT, false); - if (isLoginSuccess) { - initScreen(); - } else { - CallService.stop(this); - finish(); - } - } + initScreen(); } if (requestCode == QBRTCScreenCapturer.REQUEST_MEDIA_PROJECTION && resultCode == Activity.RESULT_OK && data != null) { @@ -199,13 +228,14 @@ private void startScreenSharing(final Intent data) { private void startSuitableFragment(boolean isInComingCall) { QBRTCSession session = WebRtcSessionManager.getInstance(this).getCurrentSession(); if (session != null) { + startLoadAbsentUsers(); if (isInComingCall) { initIncomingCallTask(); - startLoadAbsentUsers(); addIncomeCallFragment(); + startLoadAbsentUsers(); checkPermission(); } else { - addConversationFragment(isInComingCall); + addConversationFragment(false); getIntent().removeExtra(Consts.EXTRA_IS_INCOMING_CALL); sharedPrefsHelper.save(Consts.EXTRA_IS_INCOMING_CALL, false); } @@ -256,8 +286,8 @@ private void startLoadAbsentUsers() { ArrayList usersFromDb = dbManager.getAllUsers(); ArrayList allParticipantsOfCall = new ArrayList<>(); - if (opponentsIdsList != null) { - allParticipantsOfCall.addAll(opponentsIdsList); + if (opponentIds != null) { + allParticipantsOfCall.addAll(opponentIds); } if (isInComingCall) { @@ -279,12 +309,6 @@ public void onSuccess(ArrayList users, Bundle params) { } } - private void initSettingsStrategy() { - if (opponentsIdsList != null) { - SettingsUtil.setSettingsStrategy(opponentsIdsList, sharedPref, this); - } - } - private void initIncomingCallTask() { showIncomingCallWindowTaskHandler = new Handler(Looper.myLooper()); showIncomingCallWindowTask = new Runnable() { @@ -310,7 +334,9 @@ public void hangUpCurrentSession() { private void startIncomeCallTimer(long time) { Log.d(TAG, "startIncomeCallTimer"); - showIncomingCallWindowTaskHandler.postAtTime(showIncomingCallWindowTask, SystemClock.uptimeMillis() + time); + if (showIncomingCallWindowTaskHandler != null && showIncomingCallWindowTask != null) { + showIncomingCallWindowTaskHandler.postAtTime(showIncomingCallWindowTask, SystemClock.uptimeMillis() + time); + } } private void stopIncomeCallTimer() { @@ -318,33 +344,6 @@ private void stopIncomeCallTimer() { showIncomingCallWindowTaskHandler.removeCallbacks(showIncomingCallWindowTask); } - @Override - protected void onResume() { - super.onResume(); - bindCallService(); - } - - @Override - protected void onPause() { - super.onPause(); - unbindService(callServiceConnection); - if (callService != null) { - removeListeners(); - } - } - - @Override - public void finish() { - CallService.stop(this); - OpponentsActivity.start(this); - super.finish(); - } - - @Override - public void onBackPressed() { - // To prevent returning from Call Fragment - } - private void addIncomeCallFragment() { Log.d(TAG, "Adding IncomeCallFragment"); if (callService.currentSessionExist()) { @@ -364,32 +363,30 @@ private void addConversationFragment(boolean isIncomingCall) { FragmentExecuotr.addFragment(getSupportFragmentManager(), R.id.fragment_container, conversationFragment, conversationFragment.getClass().getSimpleName()); } - private void showNotificationPopUp(final int text, final boolean show) { - runOnUiThread(new Runnable() { - @Override - public void run() { - LinearLayout connectionView = (LinearLayout) View.inflate(CallActivity.this, R.layout.connection_popup, null); - if (show) { - ((TextView) connectionView.findViewById(R.id.notification)).setText(text); - if (connectionView.getParent() == null) { - ((ViewGroup) CallActivity.this.findViewById(R.id.fragment_container)).addView(connectionView); - } - } else { - ((ViewGroup) CallActivity.this.findViewById(R.id.fragment_container)).removeView(connectionView); - } + private void showConnectionPopUp() { + runOnUiThread(() -> { + ((TextView) connectionView.findViewById(R.id.notification)).setText(R.string.connection_was_lost); + if (connectionView.getParent() == null) { + ((ViewGroup) CallActivity.this.findViewById(R.id.fragment_container)).addView(connectionView); } }); } + private void hideConnectionPopUp() { + runOnUiThread(() -> { + ((ViewGroup) CallActivity.this.findViewById(R.id.fragment_container)).removeView(connectionView); + }); + } + private class ConnectionListenerImpl extends AbstractConnectionListener { @Override public void connectionClosedOnError(Exception e) { - showNotificationPopUp(R.string.connection_was_lost, true); + showConnectionPopUp(); } @Override public void reconnectionSuccessful() { - showNotificationPopUp(R.string.connection_was_lost, false); + hideConnectionPopUp(); } } @@ -480,9 +477,7 @@ public void onSessionClosed(final QBRTCSession session) { @Override public void onCallRejectByUser(QBRTCSession session, Integer userID, Map userInfo) { - if (callService.isCurrentSession(session)) { - callService.stopRingtone(); - } + // empty } @Override @@ -603,7 +598,7 @@ public boolean currentSessionExist() { @Override public List getOpponents() { - return callService.getOpponents(); + return callService.getOpponentIds(); } @Override @@ -692,22 +687,11 @@ public void onServiceConnected(ComponentName name, IBinder service) { CallService.CallServiceBinder binder = (CallService.CallServiceBinder) service; callService = binder.getService(); if (callService.currentSessionExist()) { - if (QBChatService.getInstance().isLoggedIn()) { - initScreen(); - } else { - login(); - } + initScreen(); } else { finish(); } } - - private void login() { - QBUser qbUser = SharedPrefsHelper.getInstance().getQbUser(); - Intent tempIntent = new Intent(CallActivity.this, LoginService.class); - PendingIntent pendingIntent = createPendingResult(Consts.EXTRA_LOGIN_RESULT_CODE, tempIntent, 0); - LoginService.start(CallActivity.this, qbUser, pendingIntent); - } } private class CallTimerCallback implements CallService.CallTimerListener { @@ -726,7 +710,6 @@ public interface OnChangeAudioDevice { void audioDeviceChanged(AppRTCAudioManager.AudioDevice newAudioDevice); } - public interface CurrentCallStateCallback { void onCallStarted(); diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/LoginActivity.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/LoginActivity.java index 4b659c839..5fb9b8ce1 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/LoginActivity.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/LoginActivity.java @@ -12,9 +12,10 @@ import android.view.MenuItem; import android.widget.EditText; +import androidx.annotation.Nullable; + import com.quickblox.core.QBEntityCallback; import com.quickblox.core.exception.QBResponseException; -import com.quickblox.core.helper.Utils; import com.quickblox.sample.videochat.java.App; import com.quickblox.sample.videochat.java.R; import com.quickblox.sample.videochat.java.services.LoginService; @@ -27,17 +28,13 @@ import com.quickblox.users.QBUsers; import com.quickblox.users.model.QBUser; -import androidx.annotation.Nullable; - public class LoginActivity extends BaseActivity { private String TAG = LoginActivity.class.getSimpleName(); - private static final int MIN_LENGTH = 3; - private EditText userLoginEditText; - private EditText userFullNameEditText; + private EditText userDisplayNameEditText; - private QBUser userForSave; + private QBUser currentUser; public static void start(Context context) { Intent intent = new Intent(context, LoginActivity.class); @@ -57,8 +54,8 @@ private void initUI() { userLoginEditText = findViewById(R.id.user_login); userLoginEditText.addTextChangedListener(new LoginEditTextWatcher(userLoginEditText)); - userFullNameEditText = findViewById(R.id.user_full_name); - userFullNameEditText.addTextChangedListener(new LoginEditTextWatcher(userFullNameEditText)); + userDisplayNameEditText = findViewById(R.id.user_display_name); + userDisplayNameEditText.addTextChangedListener(new LoginEditTextWatcher(userDisplayNameEditText)); } @Override @@ -71,12 +68,23 @@ public boolean onCreateOptionsMenu(Menu menu) { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_login_user_done: - if (ValidationUtils.isLoginValid(this, userLoginEditText) && - ValidationUtils.isFoolNameValid(this, userFullNameEditText)) { - hideKeyboard(); - userForSave = createUserWithEnteredData(); - startSignUpNewUser(userForSave); + boolean isNotValidLogin = !ValidationUtils.isLoginValid(userLoginEditText.getText().toString()); + if (isNotValidLogin) { + userLoginEditText.setError(getApplicationContext().getString(R.string.error_login)); + return false; + } + + boolean isNotValidDisplayName = !ValidationUtils.isDisplayNameValid(userDisplayNameEditText.getText().toString()); + if (isNotValidDisplayName) { + userDisplayNameEditText.setError(getApplicationContext().getString(R.string.error_display_name)); + return false; } + + hideKeyboard(); + String login = userLoginEditText.getText().toString(); + String fullName = userDisplayNameEditText.getText().toString(); + currentUser = createCurrentUser(login, fullName); + signUp(currentUser); return true; default: @@ -86,17 +94,17 @@ public boolean onOptionsItemSelected(MenuItem item) { private void hideKeyboard() { KeyboardUtils.hideKeyboard(userLoginEditText); - KeyboardUtils.hideKeyboard(userFullNameEditText); + KeyboardUtils.hideKeyboard(userDisplayNameEditText); } - private void startSignUpNewUser(final QBUser newUser) { + private void signUp(final QBUser user) { Log.d(TAG, "SignUp New User"); showProgressDialog(R.string.dlg_creating_new_user); - requestExecutor.signUpNewUser(newUser, new QBEntityCallback() { + requestExecutor.signUpNewUser(user, new QBEntityCallback() { @Override public void onSuccess(QBUser result, Bundle params) { Log.d(TAG, "SignUp Successful"); - saveUserData(newUser); + saveUser(user); loginToChat(result); } @@ -104,7 +112,7 @@ public void onSuccess(QBUser result, Bundle params) { public void onError(QBResponseException e) { Log.d(TAG, "Error SignUp" + e.getMessage()); if (e.getHttpStatusCode() == Consts.ERR_LOGIN_ALREADY_TAKEN_HTTP_STATUS) { - signInCreatedUser(newUser); + signIn(user); } else { hideProgressDialog(); ToastUtils.longToast(R.string.sign_up_error); @@ -114,31 +122,26 @@ public void onError(QBResponseException e) { ); } - private void loginToChat(final QBUser qbUser) { - qbUser.setPassword(App.USER_DEFAULT_PASSWORD); - userForSave = qbUser; - startLoginService(qbUser); + private void loginToChat(final QBUser user) { + user.setPassword(App.USER_DEFAULT_PASSWORD); + currentUser = user; + startLoginService(user); } - private void saveUserData(QBUser qbUser) { + private void saveUser(QBUser user) { SharedPrefsHelper sharedPrefsHelper = SharedPrefsHelper.getInstance(); - sharedPrefsHelper.saveQbUser(qbUser); - } - - private QBUser createUserWithEnteredData() { - return createQBUserWithCurrentData(String.valueOf(userLoginEditText.getText()), - String.valueOf(userFullNameEditText.getText())); + sharedPrefsHelper.saveUser(user); } - private QBUser createQBUserWithCurrentData(String userLogin, String userFullName) { - QBUser qbUser = null; + private QBUser createCurrentUser(String userLogin, String userFullName) { + QBUser user = null; if (!TextUtils.isEmpty(userLogin) && !TextUtils.isEmpty(userFullName)) { - qbUser = new QBUser(); - qbUser.setLogin(userLogin); - qbUser.setFullName(userFullName); - qbUser.setPassword(App.USER_DEFAULT_PASSWORD); + user = new QBUser(); + user.setLogin(userLogin); + user.setFullName(userFullName); + user.setPassword(App.USER_DEFAULT_PASSWORD); } - return qbUser; + return user; } @Override @@ -150,12 +153,12 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { String errorMessage = data.getStringExtra(Consts.EXTRA_LOGIN_ERROR_MESSAGE); if (isLoginSuccess) { - saveUserData(userForSave); - signInCreatedUser(userForSave); + saveUser(currentUser); + signIn(currentUser); } else { ToastUtils.longToast(getString(R.string.login_chat_login_error) + errorMessage); - userLoginEditText.setText(userForSave.getLogin()); - userFullNameEditText.setText(userForSave.getFullName()); + userLoginEditText.setText(currentUser.getLogin()); + userDisplayNameEditText.setText(currentUser.getFullName()); } } } @@ -165,14 +168,14 @@ public void onBackPressed() { finish(); } - private void signInCreatedUser(final QBUser qbUser) { + private void signIn(final QBUser user) { Log.d(TAG, "SignIn Started"); - requestExecutor.signInUser(qbUser, new QBEntityCallbackImpl() { + requestExecutor.signInUser(user, new QBEntityCallbackImpl() { @Override public void onSuccess(QBUser user, Bundle params) { Log.d(TAG, "SignIn Successful"); - sharedPrefsHelper.saveQbUser(userForSave); - updateUserOnServer(qbUser); + sharedPrefsHelper.saveUser(currentUser); + updateUserOnServer(user); } @Override @@ -208,12 +211,8 @@ private void startLoginService(QBUser qbUser) { LoginService.start(this, qbUser, pendingIntent); } - private String getCurrentDeviceId() { - return Utils.generateDeviceId(); - } - private class LoginEditTextWatcher implements TextWatcher { - private EditText editText; + private final EditText editText; private LoginEditTextWatcher(EditText editText) { this.editText = editText; @@ -221,7 +220,7 @@ private LoginEditTextWatcher(EditText editText) { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { - + // empty } @Override @@ -231,7 +230,7 @@ public void onTextChanged(CharSequence s, int start, int before, int count) { @Override public void afterTextChanged(Editable s) { - + // empty } } } \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/OpponentsActivity.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/OpponentsActivity.java index 4a6e1aac1..5011c551c 100755 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/OpponentsActivity.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/OpponentsActivity.java @@ -9,7 +9,10 @@ import android.util.Log; import android.view.Menu; import android.view.MenuItem; -import android.view.View; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import com.quickblox.chat.QBChatService; import com.quickblox.core.QBEntityCallback; @@ -20,7 +23,9 @@ import com.quickblox.messages.services.SubscribeService; import com.quickblox.sample.videochat.java.R; import com.quickblox.sample.videochat.java.adapters.UsersAdapter; -import com.quickblox.sample.videochat.java.db.QbUsersDbManager; +import com.quickblox.sample.videochat.java.db.UsersDbManager; +import com.quickblox.sample.videochat.java.executor.Executor; +import com.quickblox.sample.videochat.java.executor.ExecutorTask; import com.quickblox.sample.videochat.java.services.CallService; import com.quickblox.sample.videochat.java.services.LoginService; import com.quickblox.sample.videochat.java.utils.CollectionsUtils; @@ -40,10 +45,6 @@ import java.util.ArrayList; import java.util.List; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - /** * QuickBlox team */ @@ -61,8 +62,7 @@ public class OpponentsActivity extends BaseActivity { private int currentPage = 0; private Boolean isLoading = false; private Boolean hasNextPage = true; - - private QbUsersDbManager dbManager; + private UsersDbManager dbManager; private PermissionsChecker checker; public static void start(Context context) { @@ -75,8 +75,8 @@ public static void start(Context context) { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_select_users); - currentUser = SharedPrefsHelper.getInstance().getQbUser(); - dbManager = QbUsersDbManager.getInstance(getApplicationContext()); + currentUser = SharedPrefsHelper.getInstance().getUser(); + dbManager = UsersDbManager.getInstance(); checker = new PermissionsChecker(getApplicationContext()); initDefaultActionBar(); @@ -120,28 +120,28 @@ private void startPermissionsActivity(boolean checkOnlyAudio) { private void loadUsers() { isLoading = true; showProgressDialog(R.string.dlg_loading_opponents); - currentPage +=1; ArrayList rules = new ArrayList<>(); rules.add(new GenericQueryRule(ORDER_RULE, ORDER_DESC_UPDATED)); + int nextPage = currentPage + 1; + QBPagedRequestBuilder requestBuilder = new QBPagedRequestBuilder(); + requestBuilder.setRules(rules); + requestBuilder.setPerPage(PER_PAGE_SIZE_100); + requestBuilder.setPage(nextPage); - QBPagedRequestBuilder qbPagedRequestBuilder = new QBPagedRequestBuilder(); - qbPagedRequestBuilder.setRules(rules); - qbPagedRequestBuilder.setPerPage(PER_PAGE_SIZE_100); - qbPagedRequestBuilder.setPage(currentPage); - - QBUsers.getUsers(qbPagedRequestBuilder).performAsync(new QBEntityCallback>() { + QBUsers.getUsers(requestBuilder).performAsync(new QBEntityCallback>() { @Override public void onSuccess(ArrayList qbUsers, Bundle bundle) { Log.d(TAG, "Successfully loaded users"); dbManager.saveAllUsers(qbUsers, true); + currentPage = bundle.getInt("current_page"); - int totalPagesFromParams = (int) bundle.get(TOTAL_PAGES_BUNDLE_PARAM); - if (currentPage >= totalPagesFromParams) { + int totalPages = (int) bundle.get(TOTAL_PAGES_BUNDLE_PARAM); + if (currentPage >= totalPages) { hasNextPage = false; } if (currentPage == 1) { - initUsersList(); + updateUsers(); } else { usersAdapter.addUsers(qbUsers); } @@ -154,7 +154,6 @@ public void onError(QBResponseException e) { Log.d(TAG, "Error load users" + e.getMessage()); hideProgressDialog(); isLoading = false; - currentPage -=1; showErrorSnackbar(R.string.loading_users_error, e, v -> loadUsers()); } }); @@ -162,29 +161,25 @@ public void onError(QBResponseException e) { private void initUi() { usersRecyclerview = findViewById(R.id.list_select_users); - } - - private void initUsersList() { - List currentOpponentsList = dbManager.getAllUsers(); - Log.d(TAG, "initUsersList currentOpponentsList= " + currentOpponentsList); - currentOpponentsList.remove(sharedPrefsHelper.getQbUser()); if (usersAdapter == null) { - usersAdapter = new UsersAdapter(this, currentOpponentsList); - usersAdapter.setSelectedItemsCountsChangedListener(new UsersAdapter.SelectedItemsCountChangedListener() { - @Override - public void onCountSelectedItemsChanged(Integer count) { - updateActionBar(count); - } - }); + List opponents = dbManager.getAllUsers(); + opponents.remove(sharedPrefsHelper.getUser()); + usersAdapter = new UsersAdapter(this, opponents); + usersAdapter.setSelectedItemsListener(this::updateActionBar); usersRecyclerview.setLayoutManager(new LinearLayoutManager(this)); usersRecyclerview.setAdapter(usersAdapter); usersRecyclerview.addOnScrollListener(new ScrollListener((LinearLayoutManager) usersRecyclerview.getLayoutManager())); - } else { - usersAdapter.updateUsersList(currentOpponentsList); } } + private void updateUsers() { + List opponents = dbManager.getAllUsers(); + Log.d(TAG, "updateUsers opponents= " + opponents); + opponents.remove(sharedPrefsHelper.getUser()); + usersAdapter.updateUsers(opponents); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { if (usersAdapter != null && !usersAdapter.getSelectedUsers().isEmpty()) { @@ -206,12 +201,8 @@ public boolean onOptionsItemSelected(MenuItem item) { loadUsers(); return true; - case R.id.settings: - SettingsActivity.start(this); - return true; - case R.id.log_out: - unsubscribeFromPushesAndLogout(); + unsubscribeFromPushes(this::logout); return true; case R.id.start_video_call: @@ -250,8 +241,8 @@ private boolean checkIsLoggedInChat() { } private void startLoginService() { - if (sharedPrefsHelper.hasQbUser()) { - QBUser qbUser = sharedPrefsHelper.getQbUser(); + if (sharedPrefsHelper.hasUser()) { + QBUser qbUser = sharedPrefsHelper.getUser(); LoginService.start(this, qbUser); } } @@ -264,43 +255,60 @@ private void startCall(boolean isVideoCall) { return; } - ArrayList opponentsList = CollectionsUtils.getIdsSelectedOpponents(usersAdapter.getSelectedUsers()); + ArrayList opponents = CollectionsUtils.getIdsSelectedOpponents(usersAdapter.getSelectedUsers()); QBRTCTypes.QBConferenceType conferenceType = isVideoCall ? QBRTCTypes.QBConferenceType.QB_CONFERENCE_TYPE_VIDEO : QBRTCTypes.QBConferenceType.QB_CONFERENCE_TYPE_AUDIO; Log.d(TAG, "conferenceType = " + conferenceType); QBRTCClient qbrtcClient = QBRTCClient.getInstance(getApplicationContext()); - QBRTCSession newQbRtcSession = qbrtcClient.createNewSessionWithOpponents(opponentsList, conferenceType); - WebRtcSessionManager.getInstance(this).setCurrentSession(newQbRtcSession); - - // Make Users FullName Strings and ID's list for iOS VOIP push - String newSessionID = newQbRtcSession.getSessionID(); - ArrayList opponentsIDsList = new ArrayList<>(); - ArrayList opponentsNamesList = new ArrayList<>(); - List usersInCall = usersAdapter.getSelectedUsers(); + QBRTCSession session = qbrtcClient.createNewSessionWithOpponents(opponents, conferenceType); + WebRtcSessionManager.getInstance(this).setCurrentSession(session); + String sessionId = session.getSessionID(); + ArrayList opponentIds = new ArrayList<>(); + ArrayList opponentNames = new ArrayList<>(); + List selectedUsers = usersAdapter.getSelectedUsers(); // the Caller in exactly first position is needed regarding to iOS 13 functionality - usersInCall.add(0, currentUser); + selectedUsers.add(0, currentUser); - for (QBUser user : usersInCall) { + for (QBUser user : selectedUsers) { String userId = user.getId().toString(); - String userName = ""; - if (TextUtils.isEmpty(user.getFullName())) { - userName = user.getLogin(); - } else { - userName = user.getFullName(); - } - - opponentsIDsList.add(userId); - opponentsNamesList.add(userName); + String userName = TextUtils.isEmpty(user.getFullName()) ? user.getLogin() : user.getFullName(); + opponentIds.add(userId); + opponentNames.add(userName); } - String opponentsIDsString = TextUtils.join(",", opponentsIDsList); - String opponentNamesString = TextUtils.join(",", opponentsNamesList); + String idsInLine = TextUtils.join(",", opponentIds); + String namesInLine = TextUtils.join(",", opponentNames); + + Log.d(TAG, "New Session with Id: " + sessionId + "\n Users in Call: " + "\n" + idsInLine + "\n" + namesInLine); + + for (Integer opponentId : opponents) { + Executor.addTask(new ExecutorTask() { + @Override + public Boolean onBackground() throws Exception { + long TIMEOUT_3_SECONDS = 3000L; + return QBChatService.getInstance().getPingManager().pingUser(opponentId, TIMEOUT_3_SECONDS); + } - Log.d(TAG, "New Session with ID: " + newSessionID + "\n Users in Call: " + "\n" + opponentsIDsString + "\n" + opponentNamesString); - PushNotificationSender.sendPushMessage(opponentsList, currentUser.getFullName(), newSessionID, opponentsIDsString, opponentNamesString, isVideoCall); + @Override + public void onForeground(Boolean result) { + if (result) { + Log.d(TAG, "Participant with id: " + opponentId + " is online. There is no need to send a VoIP notification."); + } else { + String name = TextUtils.isEmpty(currentUser.getFullName()) ? currentUser.getLogin() : currentUser.getFullName(); + PushNotificationSender.sendPushMessage(opponentId, name, sessionId, + idsInLine, namesInLine, isVideoCall); + } + } + + @Override + public void onError(Exception exception) { + Log.d(TAG, "onError: " + exception); + } + }); + } CallActivity.start(this, false); } @@ -319,41 +327,29 @@ private void updateActionBar(int countSelectedUsers) { invalidateOptionsMenu(); } - private void logOut() { + private void logout() { Log.d(TAG, "Removing User data, and Logout"); LoginService.logout(this); requestExecutor.signOut(new QBEntityCallback() { @Override public void onSuccess(Void aVoid, Bundle bundle) { - UsersUtils.removeUserData(getApplicationContext()); + UsersUtils.removeUserData(); startLoginActivity(); } @Override public void onError(QBResponseException e) { - showErrorSnackbar(R.string.error, e, new View.OnClickListener() { - @Override - public void onClick(View v) { - logOut(); - } - }); + showErrorSnackbar(R.string.error, e, v -> unsubscribeFromPushes(() -> logout())); } }); } - private void unsubscribeFromPushesAndLogout() { + private void unsubscribeFromPushes(Callback callback) { if (QBPushManager.getInstance().isSubscribedToPushes()) { - QBPushManager.getInstance().addListener(new QBPushSubscribeListenerImpl() { - @Override - public void onSubscriptionDeleted(boolean success) { - Log.d(TAG, "Subscription Deleted"); - QBPushManager.getInstance().removeListener(this); - logOut(); - } - }); + QBPushManager.getInstance().addListener(new SubscribeListener(TAG, callback)); SubscribeService.unSubscribeFromPushes(OpponentsActivity.this); } else { - logOut(); + callback.notifyCallback(); } } @@ -384,20 +380,49 @@ public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { } } - private class QBPushSubscribeListenerImpl implements QBPushManager.QBSubscribeListener { + private class SubscribeListener implements QBPushManager.QBSubscribeListener { + private final String tag; + private final Callback callback; + + public SubscribeListener(String tag, Callback callback) { + this.tag = tag; + this.callback = callback; + } + @Override - public void onSubscriptionCreated() { + public void onSubscriptionDeleted(boolean success) { + QBPushManager.getInstance().removeListener(this); + callback.notifyCallback(); + } + @Override + public void onSubscriptionCreated() { + // empty } @Override public void onSubscriptionError(Exception e, int i) { - + // empty } @Override - public void onSubscriptionDeleted(boolean b) { + public boolean equals(Object obj) { + if (obj instanceof SubscribeListener) { + return tag.equals(((SubscribeListener) obj).tag); + } + return false; + } + @Override + public int hashCode() { + final int prime = 31; + int hash = 1; + hash = prime * hash + tag.hashCode(); + return hash; } } + + private interface Callback { + void notifyCallback(); + } } \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/SettingsActivity.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/SettingsActivity.java deleted file mode 100755 index cfbb60ff0..000000000 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/SettingsActivity.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.quickblox.sample.videochat.java.activities; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.EditTextPreference; -import android.preference.Preference; -import android.view.View; - -import com.quickblox.sample.videochat.java.R; -import com.quickblox.sample.videochat.java.fragments.SettingsFragment; -import com.quickblox.sample.videochat.java.utils.ToastUtils; -import com.quickblox.sample.videochat.java.view.SeekBarPreference; - -/** - * QuickBlox team - */ -public class SettingsActivity extends BaseActivity implements SharedPreferences.OnSharedPreferenceChangeListener { - - - private static final int MAX_VIDEO_START_BITRATE = 2000; - private String bitrateStringKey; - private SettingsFragment settingsFragment; - - public static void start(Context context) { - Intent intent = new Intent(context, SettingsActivity.class); - context.startActivity(intent); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - initActionBar(); - - // Display the fragment as the main content. - settingsFragment = new SettingsFragment(); - getFragmentManager().beginTransaction() - .replace(android.R.id.content, settingsFragment) - .commit(); - bitrateStringKey = getString(R.string.pref_startbitratevalue_key); - } - - private void initActionBar() { - actionBar.setTitle(R.string.actionbar_title_settings); - } - - @Override - protected void onResume() { - super.onResume(); - SharedPreferences sharedPreferences = - settingsFragment.getPreferenceScreen().getSharedPreferences(); - sharedPreferences.registerOnSharedPreferenceChangeListener(this); - } - - @Override - protected void onPause() { - super.onPause(); - SharedPreferences sharedPreferences = - settingsFragment.getPreferenceScreen().getSharedPreferences(); - sharedPreferences.unregisterOnSharedPreferenceChangeListener(this); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (key.equals(bitrateStringKey)) { - int bitrateValue = sharedPreferences.getInt(bitrateStringKey, Integer.parseInt( - getString(R.string.pref_startbitratevalue_default))); - if (bitrateValue == 0) { - setDefaultstartingBitrate(sharedPreferences); - return; - } - int startBitrate = bitrateValue; - if (startBitrate > MAX_VIDEO_START_BITRATE) { - ToastUtils.longToast("Max value is:" + MAX_VIDEO_START_BITRATE); - setDefaultstartingBitrate(sharedPreferences); - } - } - } - - private void setDefaultstartingBitrate(SharedPreferences sharedPreferences) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putInt(bitrateStringKey, - Integer.parseInt(getString(R.string.pref_startbitratevalue_default))); - editor.apply(); - updateSummary(sharedPreferences, bitrateStringKey); - } - - private void updateSummary(SharedPreferences sharedPreferences, String key) { - Preference updatedPref = settingsFragment.findPreference(key); - // Set summary to be the user-description for the selected value - if (updatedPref instanceof EditTextPreference) { - ((EditTextPreference) updatedPref).setText(sharedPreferences.getString(key, "")); - } else if (updatedPref instanceof SeekBarPreference) { - updatedPref.setSummary(String.valueOf(sharedPreferences.getInt(key, 0))); - } else { - updatedPref.setSummary(sharedPreferences.getString(key, "")); - } - } -} \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/SplashActivity.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/SplashActivity.java index a0fd90d52..265f42c09 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/SplashActivity.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/SplashActivity.java @@ -50,8 +50,8 @@ protected void onCreate(Bundle savedInstanceState) { } private void runNextScreen() { - if (sharedPrefsHelper.hasQbUser()) { - LoginService.start(SplashActivity.this, sharedPrefsHelper.getQbUser()); + if (sharedPrefsHelper.hasUser()) { + LoginService.start(SplashActivity.this, sharedPrefsHelper.getUser()); OpponentsActivity.start(SplashActivity.this); } else { new Handler().postDelayed(new Runnable() { diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/adapters/OpponentsFromCallAdapter.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/adapters/OpponentsFromCallAdapter.java index 808ec989c..b837a3cfd 100755 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/adapters/OpponentsFromCallAdapter.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/adapters/OpponentsFromCallAdapter.java @@ -1,8 +1,8 @@ package com.quickblox.sample.videochat.java.adapters; import android.content.Context; +import android.text.TextUtils; import android.util.Log; -import android.util.SparseIntArray; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -11,18 +11,17 @@ import android.widget.ProgressBar; import android.widget.TextView; +import androidx.recyclerview.widget.RecyclerView; + import com.quickblox.sample.videochat.java.R; import com.quickblox.sample.videochat.java.fragments.BaseConversationFragment; import com.quickblox.sample.videochat.java.utils.QBRTCSessionUtils; import com.quickblox.users.model.QBUser; -import com.quickblox.videochat.webrtc.QBRTCSession; import com.quickblox.videochat.webrtc.QBRTCTypes; import com.quickblox.videochat.webrtc.view.QBRTCSurfaceView; import java.util.List; -import androidx.recyclerview.widget.RecyclerView; - /** * QuickBlox team */ @@ -96,7 +95,14 @@ public void onShowOpponent(int callerId) { public void onBindViewHolder(ViewHolder holder, int position) { final QBUser user = opponents.get(position); int userID = user.getId(); - holder.opponentsName.setText(user.getFullName()); + + String name; + if (TextUtils.isEmpty(user.getFullName())) { + name = user.getLogin(); + } else { + name = user.getFullName(); + } + holder.opponentsName.setText(name); holder.getOpponentView().setId(user.getId()); holder.setUserId(userID); diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/adapters/UsersAdapter.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/adapters/UsersAdapter.java index d6c44ebca..153d5a9e6 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/adapters/UsersAdapter.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/adapters/UsersAdapter.java @@ -8,6 +8,9 @@ import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + import com.quickblox.sample.videochat.java.R; import com.quickblox.sample.videochat.java.utils.UiUtils; import com.quickblox.users.model.QBUser; @@ -15,16 +18,11 @@ import java.util.ArrayList; import java.util.List; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - public class UsersAdapter extends RecyclerView.Adapter { - - private Context context; - List usersList; - List selectedUsers; - private SelectedItemsCountChangedListener selectedItemsCountChangedListener; - + private final Context context; + private List usersList; + private final List selectedUsers; + private SelectedItemsListener selectedItemsListener; public UsersAdapter(Context context, List usersList) { this.context = context; @@ -32,18 +30,16 @@ public UsersAdapter(Context context, List usersList) { this.selectedUsers = new ArrayList<>(); } - public List getSelectedUsers() { return selectedUsers; } - public void setSelectedItemsCountsChangedListener(SelectedItemsCountChangedListener selectedItemsCountChanged) { - if (selectedItemsCountChanged != null) { - this.selectedItemsCountChangedListener = selectedItemsCountChanged; + public void setSelectedItemsListener(SelectedItemsListener selectedItemsListener) { + if (selectedItemsListener != null) { + this.selectedItemsListener = selectedItemsListener; } } - @NonNull @Override public UsersAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @@ -64,12 +60,9 @@ public void onBindViewHolder(@NonNull UsersAdapter.ViewHolder holder, int positi holder.opponentIcon.setBackgroundDrawable(UiUtils.getColorCircleDrawable(user.getId())); holder.opponentIcon.setImageResource(R.drawable.ic_person); } - holder.rootLayout.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - toggleSelection(user); - selectedItemsCountChangedListener.onCountSelectedItemsChanged(selectedUsers.size()); - } + holder.rootLayout.setOnClickListener(v -> { + toggleSelection(user); + selectedItemsListener.onSelectedItems(selectedUsers.size()); }); } @@ -78,12 +71,15 @@ public int getItemCount() { return usersList.size(); } - public void updateUsersList(List usersList) { + public void updateUsers(List usersList) { this.usersList = usersList; notifyDataSetChanged(); } public void addUsers(List users) { + if (users == null) { + return; + } for (QBUser user : users) { if (!usersList.contains(user)) { usersList.add(user); @@ -93,7 +89,7 @@ public void addUsers(List users) { } private void toggleSelection(QBUser qbUser) { - if (selectedUsers.contains(qbUser)){ + if (selectedUsers.contains(qbUser)) { selectedUsers.remove(qbUser); } else { selectedUsers.add(qbUser); @@ -114,7 +110,7 @@ public ViewHolder(@NonNull View view) { } } - public interface SelectedItemsCountChangedListener { - void onCountSelectedItemsChanged(Integer count); + public interface SelectedItemsListener { + void onSelectedItems(Integer count); } -} +} \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/db/DbHelper.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/db/DbHelper.java index ff8258f1d..399cee2ab 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/db/DbHelper.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/db/DbHelper.java @@ -1,13 +1,12 @@ package com.quickblox.sample.videochat.java.db; -import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; +import com.quickblox.sample.videochat.java.App; public class DbHelper extends SQLiteOpenHelper { - private String TAG = DbHelper.class.getSimpleName(); private static final String DB_NAME = "groupchatwebrtcDB"; @@ -20,9 +19,8 @@ public class DbHelper extends SQLiteOpenHelper { public static final String DB_COLUMN_USER_PASSWORD = "userPass"; public static final String DB_COLUMN_USER_TAG = "userTag"; - - public DbHelper(Context context) { - super(context, DB_NAME, null, 1); + public DbHelper() { + super(App.getInstance(), DB_NAME, null, 1); } @Override diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/db/QbUsersDbManager.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/db/UsersDbManager.java similarity index 88% rename from sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/db/QbUsersDbManager.java rename to sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/db/UsersDbManager.java index bed1eac39..9f278d8d3 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/db/QbUsersDbManager.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/db/UsersDbManager.java @@ -1,7 +1,6 @@ package com.quickblox.sample.videochat.java.db; import android.content.ContentValues; -import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.util.Log; @@ -12,28 +11,25 @@ import java.util.ArrayList; import java.util.List; +public class UsersDbManager { + private static final String TAG = UsersDbManager.class.getSimpleName(); -public class QbUsersDbManager { - private static String TAG = QbUsersDbManager.class.getSimpleName(); + private static UsersDbManager instance; + private final DbHelper dbHelper; - private static QbUsersDbManager instance; - private Context mContext; - - private QbUsersDbManager(Context context) { - this.mContext = context; + private UsersDbManager() { + dbHelper = new DbHelper(); } - public static QbUsersDbManager getInstance(Context context) { + public static synchronized UsersDbManager getInstance() { if (instance == null) { - instance = new QbUsersDbManager(context); + instance = new UsersDbManager(); } - return instance; } public ArrayList getAllUsers() { ArrayList allUsers = new ArrayList<>(); - DbHelper dbHelper = new DbHelper(mContext); SQLiteDatabase db = dbHelper.getWritableDatabase(); Cursor c = db.query(DbHelper.DB_TABLE_NAME, null, null, null, null, null, null); @@ -68,7 +64,6 @@ public ArrayList getAllUsers() { public QBUser getUserById(Integer userId) { QBUser qbUser = null; - DbHelper dbHelper = new DbHelper(mContext); SQLiteDatabase db = dbHelper.getWritableDatabase(); Cursor c = db.query(DbHelper.DB_TABLE_NAME, null, null, null, null, null, null); @@ -114,7 +109,6 @@ public void saveAllUsers(ArrayList allUsers, boolean needRemoveOldData) public void saveUser(QBUser qbUser) { ContentValues cv = new ContentValues(); - DbHelper dbHelper = new DbHelper(mContext); SQLiteDatabase db = dbHelper.getWritableDatabase(); cv.put(DbHelper.DB_COLUMN_USER_FULL_NAME, qbUser.getFullName()); cv.put(DbHelper.DB_COLUMN_USER_LOGIN, qbUser.getLogin()); @@ -127,7 +121,6 @@ public void saveUser(QBUser qbUser) { } public void clearDB() { - DbHelper dbHelper = new DbHelper(mContext); SQLiteDatabase db = dbHelper.getWritableDatabase(); db.delete(DbHelper.DB_TABLE_NAME, null, null); dbHelper.close(); diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/executor/Executor.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/executor/Executor.java new file mode 100644 index 000000000..c655ac087 --- /dev/null +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/executor/Executor.java @@ -0,0 +1,44 @@ +package com.quickblox.sample.videochat.java.executor; + +import android.os.Handler; +import android.os.Looper; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class Executor { + private final int CORE_POOL_SIZE = 3; + private final int MAX_POOL_SIZE = 3; + private final int KEEP_ALIVE_TIME = 1; + + private final BlockingQueue threadQueue = new LinkedBlockingQueue<>(); + private final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, + KEEP_ALIVE_TIME, TimeUnit.SECONDS, threadQueue); + + private static Executor instance; + + private static synchronized Executor getInstance() { + if (instance == null) { + instance = new Executor(); + } + return instance; + } + + private Executor() { + } + + public static void addTask(ExecutorTask executorTask) { + getInstance().threadPoolExecutor.execute(() -> { + Handler mainHandler = new Handler(Looper.getMainLooper()); + + try { + T result = executorTask.onBackground(); + mainHandler.post(() -> executorTask.onForeground(result)); + } catch (Exception exception) { + mainHandler.post(() -> executorTask.onError(exception)); + } + }); + } +} \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/executor/ExecutorTask.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/executor/ExecutorTask.java new file mode 100644 index 000000000..b53fb9d32 --- /dev/null +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/executor/ExecutorTask.java @@ -0,0 +1,9 @@ +package com.quickblox.sample.videochat.java.executor; + +public interface ExecutorTask { + T onBackground() throws Exception; + + void onForeground(T result); + + void onError(Exception exception); +} \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/AudioConversationFragment.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/AudioConversationFragment.java index 729da25a9..2a64291cb 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/AudioConversationFragment.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/AudioConversationFragment.java @@ -1,11 +1,14 @@ package com.quickblox.sample.videochat.java.fragments; +import android.text.TextUtils; import android.view.View; import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.TextView; import android.widget.ToggleButton; +import androidx.core.content.ContextCompat; + import com.quickblox.sample.videochat.java.R; import com.quickblox.sample.videochat.java.activities.CallActivity; import com.quickblox.sample.videochat.java.utils.CollectionsUtils; @@ -16,8 +19,6 @@ import java.util.ArrayList; -import androidx.core.content.ContextCompat; - public class AudioConversationFragment extends BaseConversationFragment implements CallActivity.OnChangeAudioDevice { private static final String TAG = AudioConversationFragment.class.getSimpleName(); @@ -54,7 +55,13 @@ protected void configureToolbar() { @Override protected void configureActionBar() { - actionBar.setSubtitle(String.format(getString(R.string.subtitle_text_logged_in_as), currentUser.getFullName())); + String name; + if (TextUtils.isEmpty(currentUser.getFullName())) { + name = currentUser.getLogin(); + } else { + name = currentUser.getFullName(); + } + actionBar.setSubtitle(String.format(getString(R.string.subtitle_text_logged_in_as), name)); } @Override @@ -72,7 +79,15 @@ protected void initViews(View view) { setVisibilityAlsoOnCallTextView(); firstOpponentNameTextView = (TextView) view.findViewById(R.id.text_caller_name); - firstOpponentNameTextView.setText(opponents.get(0).getFullName()); + + QBUser user = opponents.get(0); + String name; + if (TextUtils.isEmpty(user.getFullName())) { + name = user.getLogin(); + } else { + name = user.getFullName(); + } + firstOpponentNameTextView.setText(name); otherOpponentsTextView = (TextView) view.findViewById(R.id.text_other_inc_users); otherOpponentsTextView.setText(getOtherOpponentsNames()); @@ -137,7 +152,14 @@ int getFragmentLayout() { @Override public void onOpponentsListUpdated(ArrayList newUsers) { super.onOpponentsListUpdated(newUsers); - firstOpponentNameTextView.setText(opponents.get(0).getFullName()); + QBUser user = opponents.get(0); + String name; + if (TextUtils.isEmpty(user.getFullName())) { + name = user.getLogin(); + } else { + name = user.getFullName(); + } + firstOpponentNameTextView.setText(name); otherOpponentsTextView.setText(getOtherOpponentsNames()); } diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/BaseConversationFragment.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/BaseConversationFragment.java index 776b735e2..553e7e2ae 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/BaseConversationFragment.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/BaseConversationFragment.java @@ -14,7 +14,7 @@ import com.quickblox.chat.QBChatService; import com.quickblox.sample.videochat.java.R; import com.quickblox.sample.videochat.java.activities.CallActivity; -import com.quickblox.sample.videochat.java.db.QbUsersDbManager; +import com.quickblox.sample.videochat.java.db.UsersDbManager; import com.quickblox.sample.videochat.java.services.CallService; import com.quickblox.sample.videochat.java.utils.CollectionsUtils; import com.quickblox.sample.videochat.java.utils.Consts; @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; import androidx.annotation.Nullable; @@ -34,7 +35,7 @@ public abstract class BaseConversationFragment extends BaseToolBarFragment imple private static final String TAG = BaseConversationFragment.class.getSimpleName(); public static final String MIC_ENABLED = "is_microphone_enabled"; - protected QbUsersDbManager dbManager; + protected UsersDbManager dbManager; protected WebRtcSessionManager sessionManager; private boolean isIncomingCall; @@ -109,11 +110,11 @@ private void prepareAndShowOutgoingScreen() { protected abstract void configureToolbar(); protected void initFields() { - dbManager = QbUsersDbManager.getInstance(getActivity().getApplicationContext()); + dbManager = UsersDbManager.getInstance(); sessionManager = WebRtcSessionManager.getInstance(getActivity()); currentUser = QBChatService.getInstance().getUser(); if (currentUser == null) { - currentUser = SharedPrefsHelper.getInstance().getQbUser(); + currentUser = SharedPrefsHelper.getInstance().getUser(); } if (getArguments() != null) { @@ -130,7 +131,9 @@ public void onStart() { if (isIncomingCall) { conversationFragmentCallback.acceptCall(new HashMap<>()); } else { - conversationFragmentCallback.startCall(new HashMap<>()); + Map userInfo = new HashMap<>(); + userInfo.put("timestamp",Long.toString(System.currentTimeMillis())); + conversationFragmentCallback.startCall(userInfo); } } } @@ -223,6 +226,7 @@ public void onCallStopped() { @Override public void onOpponentsListUpdated(ArrayList newUsers) { initOpponentsList(); + allOpponentsTextView.setText(CollectionsUtils.makeStringFromUsersFullNames(opponents)); } private void initOpponentsList() { @@ -232,7 +236,7 @@ private void initOpponentsList() { if (opponentsIds != null) { ArrayList usersFromDb = dbManager.getUsersByIds(opponentsIds); - opponents = UsersUtils.getListAllUsersFromIds(usersFromDb, opponentsIds); + opponents = UsersUtils.getUsersFromIds(usersFromDb, opponentsIds); } QBUser caller = dbManager.getUserById(conversationFragmentCallback.getCallerId()); diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/IncomeCallFragment.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/IncomeCallFragment.java index 532b411e9..e07967e61 100755 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/IncomeCallFragment.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/IncomeCallFragment.java @@ -16,15 +16,15 @@ import android.widget.ProgressBar; import android.widget.TextView; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; + import com.quickblox.chat.QBChatService; import com.quickblox.core.QBEntityCallback; import com.quickblox.core.exception.QBResponseException; -import com.quickblox.core.request.GenericQueryRule; -import com.quickblox.core.request.QBPagedRequestBuilder; -import com.quickblox.sample.videochat.java.App; import com.quickblox.sample.videochat.java.R; import com.quickblox.sample.videochat.java.activities.CallActivity; -import com.quickblox.sample.videochat.java.db.QbUsersDbManager; +import com.quickblox.sample.videochat.java.db.UsersDbManager; import com.quickblox.sample.videochat.java.utils.CollectionsUtils; import com.quickblox.sample.videochat.java.utils.RingtonePlayer; import com.quickblox.sample.videochat.java.utils.UiUtils; @@ -40,9 +40,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; -import androidx.appcompat.widget.Toolbar; -import androidx.fragment.app.Fragment; - /** * QuickBlox team */ @@ -59,6 +56,7 @@ public class IncomeCallFragment extends Fragment implements Serializable, View.O private ImageButton takeButton; private TextView callerNameTextView; private ProgressBar progressUserName; + private CallActivity.CurrentCallStateCallback currentCallStateCallback; private List opponentsIds; private Vibrator vibrator; @@ -67,8 +65,9 @@ public class IncomeCallFragment extends Fragment implements Serializable, View.O private RingtonePlayer ringtonePlayer; private IncomeCallFragmentCallbackListener incomeCallFragmentCallbackListener; private QBRTCSession currentSession; - private QbUsersDbManager qbUserDbManager; + private UsersDbManager qbUserDbManager; private TextView alsoOnCallText; + private TextView otherUsersTextView; @Override public void onAttach(Activity activity) { @@ -104,9 +103,22 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa return view; } + @Override + public void onResume() { + super.onResume(); + currentCallStateCallback = new CurrentCallStateCallbackImpl(); + ((CallActivity) requireActivity()).addCurrentCallStateListener(currentCallStateCallback); + } + + @Override + public void onPause() { + super.onPause(); + ((CallActivity) requireActivity()).removeCurrentCallStateListener(currentCallStateCallback); + } + private void initFields() { currentSession = WebRtcSessionManager.getInstance(getActivity()).getCurrentSession(); - qbUserDbManager = QbUsersDbManager.getInstance(getActivity().getApplicationContext()); + qbUserDbManager = UsersDbManager.getInstance(); if (currentSession != null) { opponentsIds = currentSession.getOpponents(); conferenceType = currentSession.getConferenceType(); @@ -138,7 +150,7 @@ private void initUI(View view) { progressUserName = view.findViewById(R.id.progress_bar_opponent_name); ImageView callerAvatarImageView = view.findViewById(R.id.image_caller_avatar); callerNameTextView = view.findViewById(R.id.text_caller_name); - TextView otherIncUsersTextView = view.findViewById(R.id.text_other_inc_users); + otherUsersTextView = view.findViewById(R.id.text_other_inc_users); alsoOnCallText = view.findViewById(R.id.text_also_on_call); rejectButton = view.findViewById(R.id.image_button_reject_call); takeButton = view.findViewById(R.id.image_button_accept_call); @@ -154,7 +166,7 @@ private void initUI(View view) { updateUserFromServer(); } - otherIncUsersTextView.setText(getOtherIncUsersNames()); + otherUsersTextView.setText(getOtherIncUsersNames()); setVisibilityAlsoOnCallTextView(); } } @@ -167,7 +179,7 @@ private void updateUserFromServer() { public void onSuccess(QBUser qbUser, Bundle bundle) { if (qbUser != null) { qbUserDbManager.saveUser(qbUser); - String callerName = TextUtils.isEmpty(qbUser.getFullName())? qbUser.getLogin() : qbUser.getFullName(); + String callerName = TextUtils.isEmpty(qbUser.getFullName()) ? qbUser.getLogin() : qbUser.getFullName(); callerNameTextView.setText(callerName); } progressUserName.setVisibility(View.GONE); @@ -218,7 +230,7 @@ private void stopCallNotification() { private String getOtherIncUsersNames() { ArrayList usersFromDb = qbUserDbManager.getUsersByIds(opponentsIds); ArrayList opponents = new ArrayList<>(); - opponents.addAll(UsersUtils.getListAllUsersFromIds(usersFromDb, opponentsIds)); + opponents.addAll(UsersUtils.getUsersFromIds(usersFromDb, opponentsIds)); opponents.remove(QBChatService.getInstance().getUser()); Log.d(TAG, "opponentsIds = " + opponentsIds); @@ -281,4 +293,26 @@ private void enableButtons(boolean enable) { takeButton.setEnabled(enable); rejectButton.setEnabled(enable); } + + private class CurrentCallStateCallbackImpl implements CallActivity.CurrentCallStateCallback { + @Override + public void onCallStarted() { + // empty + } + + @Override + public void onCallStopped() { + // empty + } + + @Override + public void onOpponentsListUpdated(ArrayList newUsers) { + otherUsersTextView.setText(getOtherIncUsersNames()); + } + + @Override + public void onCallTimeUpdate(String time) { + // empty + } + } } \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/SettingsFragment.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/SettingsFragment.java deleted file mode 100755 index ec9ba3522..000000000 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/SettingsFragment.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.quickblox.sample.videochat.java.fragments; - -import android.os.Bundle; -import android.preference.PreferenceFragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ListView; - -import com.quickblox.sample.videochat.java.R; - -/** - * QuickBlox team - */ -public class SettingsFragment extends PreferenceFragment { - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.preferences); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View v = super.onCreateView(inflater, container, savedInstanceState); - if (v != null) { - ListView lv = (ListView) v.findViewById(android.R.id.list); - lv.setPadding(0, 0, 0, 0); - } - return v; - } -} \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/VideoConversationFragment.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/VideoConversationFragment.java index f1f718ef6..1b0d382c3 100755 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/VideoConversationFragment.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/fragments/VideoConversationFragment.java @@ -5,6 +5,7 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.SystemClock; +import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.util.SparseArray; @@ -16,6 +17,7 @@ import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.CompoundButton; +import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; @@ -76,6 +78,7 @@ public class VideoConversationFragment extends BaseConversationFragment implemen private TextView connectionStatusLocal; private RecyclerView recyclerView; private QBRTCSurfaceView localVideoView; + private FrameLayout flLocalVideoView; private QBRTCSurfaceView remoteFullScreenVideoView; private SparseArray opponentViewHolders; @@ -86,8 +89,7 @@ public class VideoConversationFragment extends BaseConversationFragment implemen private QBRTCVideoTrack localVideoTrack; private Menu optionsMenu; private boolean isRemoteShown; - private int amountOpponents; - private int userIDFullScreen; + private int userIdFullScreen; private boolean connectionEstablished; private boolean allCallbacksInit; private boolean isCurrentCameraFront; @@ -171,7 +173,6 @@ protected void configureToolbar() { protected void initFields() { super.initFields(); localViewOnClickListener = new LocalViewOnClickListener(); - amountOpponents = opponents.size(); allOpponents = Collections.synchronizedList(new ArrayList<>(opponents.size())); allOpponents.addAll(opponents); @@ -181,14 +182,23 @@ protected void initFields() { } public void setDuringCallActionBar() { - actionBar.setDisplayShowTitleEnabled(true); - actionBar.setTitle(currentUser.getFullName()); + actionBar.setDisplayShowTitleEnabled(false); + QBUser userFullScreen; if (isPeerToPeerCall) { - actionBar.setSubtitle(getString(R.string.opponent, opponents.get(0).getFullName())); + userFullScreen = opponents.get(0); } else { - actionBar.setSubtitle(getString(R.string.opponents, String.valueOf(amountOpponents))); + userFullScreen = dbManager.getUserById(userIdFullScreen); } - + if (userFullScreen == null) { + return; + } + String name; + if (TextUtils.isEmpty(userFullScreen.getFullName())) { + name = userFullScreen.getLogin(); + } else { + name = userFullScreen.getFullName(); + } + connectionStatusLocal.setText(name); actionButtonsEnabled(true); } @@ -223,6 +233,8 @@ protected void initViews(View view) { isRemoteShown = false; localVideoView = (QBRTCSurfaceView) view.findViewById(R.id.local_video_view); + flLocalVideoView = (FrameLayout) view.findViewById(R.id.fl_local_video_view); + initCorrectSizeForLocalView(); localVideoView.setZOrderMediaOverlay(true); @@ -232,7 +244,7 @@ protected void initViews(View view) { if (!isPeerToPeerCall) { recyclerView = (RecyclerView) view.findViewById(R.id.grid_opponents); - recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), R.dimen.grid_item_divider)); + recyclerView.addItemDecoration(new DividerItemDecoration(requireActivity(), R.dimen.grid_item_divider)); recyclerView.setHasFixedSize(true); final int columnsCount = defineColumnsCount(); LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), RecyclerView.HORIZONTAL, false); @@ -247,7 +259,8 @@ public void onGlobalLayout() { } }); } - connectionStatusLocal = (TextView) view.findViewById(R.id.connection_status_local); + + connectionStatusLocal = (TextView) view.findViewById(R.id.username_full_view); cameraToggle = (ToggleButton) view.findViewById(R.id.toggle_camera); cameraToggle.setVisibility(View.VISIBLE); @@ -479,20 +492,24 @@ public void onItemClick(int position) { QBRTCTypes.QBRTCConnectionState connectionState = conversationFragmentCallback.getPeerChannel(userId); HashMap videoTrackMap = conversationFragmentCallback.getVideoTrackMap(); + OpponentsFromCallAdapter.ViewHolder holder = findHolder(userId); - if (videoTrackMap != null && !videoTrackMap.containsKey(userId) || connectionState.ordinal() == QBRTCTypes.QBRTCConnectionState.QB_RTC_CONNECTION_CLOSED.ordinal()) { + boolean isNotExistVideoTrack = videoTrackMap != null && !videoTrackMap.containsKey(userId); + boolean isConnectionStateClosed = connectionState.ordinal() == QBRTCTypes.QBRTCConnectionState.QB_RTC_CONNECTION_CLOSED.ordinal(); + + if (isNotExistVideoTrack || isConnectionStateClosed || holder == null) { return; } replaceUsersInAdapter(position); updateViewHolders(position); - swapUsersFullscreenToPreview(userId); + swapUsersFullscreenToPreview(holder, userId); } private void replaceUsersInAdapter(int position) { - for (QBUser qbUser : allOpponents) { - if (qbUser.getId() == userIDFullScreen) { - opponentsAdapter.replaceUsers(position, qbUser); + for (QBUser user : allOpponents) { + if (user.getId() == userIdFullScreen) { + opponentsAdapter.replaceUsers(position, user); break; } } @@ -504,27 +521,29 @@ private void updateViewHolders(int position) { opponentViewHolders.put(position, childViewHolder); } - @SuppressWarnings("ConstantConditions") - private void swapUsersFullscreenToPreview(int userId) { + private void swapUsersFullscreenToPreview(OpponentsFromCallAdapter.ViewHolder holder, int userId) { QBRTCVideoTrack opponentVideoTrack = conversationFragmentCallback.getVideoTrackMap().get(userId); + QBRTCVideoTrack mainVideoTrack = conversationFragmentCallback.getVideoTrackMap().get(userIdFullScreen); - QBRTCVideoTrack mainVideoTrack = conversationFragmentCallback.getVideoTrackMap().get(userIDFullScreen); + QBRTCSurfaceView remoteVideoView = holder.getOpponentView(); - QBRTCSurfaceView remoteVideoView = findHolder(userId).getOpponentView(); + if (opponentVideoTrack != null) { + fillVideoView(userId, remoteFullScreenVideoView, opponentVideoTrack); + QBUser userFullScreen = dbManager.getUserById(userIdFullScreen); + connectionStatusLocal.setText(userFullScreen.getFullName()); + } if (mainVideoTrack != null) { fillVideoView(0, remoteVideoView, mainVideoTrack); - Log.d(TAG, "RemoteVideoView Enabled"); - } - if (opponentVideoTrack != null) { - fillVideoView(userId, remoteFullScreenVideoView, opponentVideoTrack); - Log.d(TAG, "Fullscreen Enabled"); + } else { + holder.getOpponentView().setBackgroundColor(Color.BLACK); + remoteFullScreenVideoView.setBackgroundColor(Color.TRANSPARENT); } } - private void setRemoteViewMultiCall(int userID, QBRTCVideoTrack videoTrack) { + private void setRemoteViewMultiCall(int userId, QBRTCVideoTrack videoTrack) { Log.d(TAG, "setRemoteViewMultiCall fillVideoView"); - final OpponentsFromCallAdapter.ViewHolder itemHolder = getViewHolderForOpponent(userID); + final OpponentsFromCallAdapter.ViewHolder itemHolder = getViewHolderForOpponent(userId); if (itemHolder == null) { Log.d(TAG, "itemHolder == null - true"); return; @@ -535,18 +554,18 @@ private void setRemoteViewMultiCall(int userID, QBRTCVideoTrack videoTrack) { updateVideoView(remoteVideoView); Log.d(TAG, "onRemoteVideoTrackReceive fillVideoView"); if (isRemoteShown) { - Log.d(TAG, "onRemoteVideoTrackReceive User = " + userID); + Log.d(TAG, "onRemoteVideoTrackReceive User = " + userId); fillVideoView(remoteVideoView, videoTrack, true); + setRecyclerViewVisibleState(); } else { isRemoteShown = true; itemHolder.getOpponentView().release(); opponentsAdapter.removeItem(itemHolder.getAdapterPosition()); - setDuringCallActionBar(); - setRecyclerViewVisibleState(); if (remoteFullScreenVideoView != null) { - fillVideoView(userID, remoteFullScreenVideoView, videoTrack); + fillVideoView(userId, remoteFullScreenVideoView, videoTrack); updateVideoView(remoteFullScreenVideoView); } + setDuringCallActionBar(); } } } @@ -622,14 +641,13 @@ private void updateVideoView(SurfaceViewRenderer videoView) { */ private void fillVideoView(int userId, QBRTCSurfaceView videoView, QBRTCVideoTrack videoTrack) { if (userId != 0) { - userIDFullScreen = userId; + userIdFullScreen = userId; } fillVideoView(videoView, videoTrack, true); } private void setStatusForOpponent(int userId, final String status) { if (isPeerToPeerCall) { - connectionStatusLocal.setText(status); return; } @@ -669,13 +687,14 @@ private void setProgressBarForOpponentGone(int userId) { } private void setBackgroundOpponentView(final Integer userId) { - final OpponentsFromCallAdapter.ViewHolder holder = findHolder(userId); - if (holder == null) { - return; - } - - if (userId != userIDFullScreen) { - holder.getOpponentView().setBackgroundColor(Color.parseColor("#000000")); + if (userId != userIdFullScreen) { + final OpponentsFromCallAdapter.ViewHolder holder = findHolder(userId); + if (holder == null) { + return; + } + holder.getOpponentView().setBackgroundColor(Color.BLACK); + } else { + remoteFullScreenVideoView.setBackgroundColor(Color.BLACK); } } @@ -697,6 +716,7 @@ public void onConnectionClosedForUser(QBRTCSession qbrtcSession, Integer userId) if (!isPeerToPeerCall) { Log.d(TAG, "onConnectionClosedForUser videoTrackMap.remove(userId)= " + userId); setBackgroundOpponentView(userId); + setProgressBarForOpponentGone(userId); } } @@ -728,7 +748,7 @@ public void onReceiveHangUpFromUser(QBRTCSession session, Integer userId, Map videoTrackMap = new HashMap<>(); - private CallServiceBinder callServiceBinder = new CallServiceBinder(); + private final HashMap videoTrackMap = new HashMap<>(); + private final CallServiceBinder callServiceBinder = new CallServiceBinder(); private NetworkConnectionListener networkConnectionListener; private NetworkConnectionChecker networkConnectionChecker; private SessionEventsListener sessionEventsListener; @@ -94,9 +92,9 @@ public class CallService extends Service { private QBRTCClient rtcClient; private RingtonePlayer ringtonePlayer; - private CallTimerTask callTimerTask = new CallTimerTask(); - private Timer callTimer = new Timer(); - private Long callTime; + private long callTime = 0L; + private ScheduledFuture future; + private final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1); public static void start(Context context) { Intent intent = new Intent(context, CallService.class); @@ -122,7 +120,7 @@ public void onCreate() { @Override public int onStartCommand(Intent intent, int flags, int startId) { - Notification notification = initNotification(); + Notification notification = buildNotification(); startForeground(SERVICE_ID, notification); return super.onStartCommand(intent, flags, startId); } @@ -152,7 +150,7 @@ public IBinder onBind(Intent intent) { return callServiceBinder; } - private Notification initNotification() { + private Notification buildNotification() { Intent notifyIntent = new Intent(this, CallActivity.class); notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); @@ -166,7 +164,7 @@ private Notification initNotification() { String notificationTitle = getString(R.string.notification_title); String notificationText = getString(R.string.notification_text, ""); - String callTime = getCallTime(); + String callTime = modifyCallTimeToString(); if (!TextUtils.isEmpty(callTime)) { notificationText = getString(R.string.notification_text, callTime); } @@ -175,16 +173,16 @@ private Notification initNotification() { bigTextStyle.setBigContentTitle(notificationTitle); bigTextStyle.bigText(notificationText); - String channelID = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? - createNotificationChannel(CHANNEL_ID, CHANNEL_NAME) + String channelId = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? + createNotificationChannel() : getString(R.string.app_name); - NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelID); + NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId); builder.setStyle(bigTextStyle); builder.setContentTitle(notificationTitle); builder.setContentText(notificationText); builder.setWhen(System.currentTimeMillis()); - builder.setSmallIcon(R.mipmap.ic_launcher); + builder.setSmallIcon(R.drawable.ic_qb_logo); Bitmap bitmapIcon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); builder.setLargeIcon(bitmapIcon); @@ -200,8 +198,8 @@ private Notification initNotification() { } @RequiresApi(Build.VERSION_CODES.O) - private String createNotificationChannel(String channelID, String channelName) { - NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_LOW); + private String createNotificationChannel() { + NotificationChannel channel = new NotificationChannel(CallService.CHANNEL_ID, CallService.CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW); channel.setLightColor(getColor(R.color.green)); channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); @@ -209,22 +207,19 @@ private String createNotificationChannel(String channelID, String channelName) { if (manager != null) { manager.createNotificationChannel(channel); } - return channelID; + return CallService.CHANNEL_ID; } - private String getCallTime() { + private String modifyCallTimeToString() { String time = ""; - if (callTime != null) { - String format = String.format("%%0%dd", 2); - Long elapsedTime = callTime / 1000; - String seconds = String.format(format, elapsedTime % 60); - String minutes = String.format(format, elapsedTime % 3600 / 60); - String hours = String.format(format, elapsedTime / 3600); - - time = minutes + ":" + seconds; - if (!TextUtils.isEmpty(hours) && hours != "00") { - time = hours + ":" + minutes + ":" + seconds; - } + String format = String.format(Locale.getDefault(), "%%0%dd", 2); + String seconds = String.format(format, callTime % 60); + String minutes = String.format(format, callTime % 3600 / 60); + String hours = String.format(format, callTime / 3600); + + time = minutes + ":" + seconds; + if (!TextUtils.isEmpty(hours) && !hours.equals("00")) { + time = hours + ":" + minutes + ":" + seconds; } return time; } @@ -247,10 +242,7 @@ private void initRTCClient() { rtcClient = QBRTCClient.getInstance(this); rtcClient.setCameraErrorHandler(new CameraEventsListener()); - QBRTCConfig.setMaxOpponentsCount(MAX_OPPONENTS_COUNT); - QBRTCConfig.setDebugEnabled(true); - - SettingsUtil.configRTCTimers(this); + SettingsManager.applyRTCSettings(); rtcClient.prepareToProcessCalls(); } @@ -318,7 +310,6 @@ private void releaseCurrentSession() { currentSession = null; } - //Listeners public void addConnectionListener(ConnectionListener connectionListener) { QBChatService.getInstance().addConnectionListener(connectionListener); } @@ -371,7 +362,6 @@ public void removeSessionEventsListener(QBRTCSessionEventsCallback callback) { rtcClient.removeSessionsCallbacksListener(callback); } - // Common methods public void acceptCall(Map userInfo) { if (currentSession != null) { currentSession.acceptCall(userInfo); @@ -432,7 +422,7 @@ public Integer getCallerId() { } } - public List getOpponents() { + public List getOpponentIds() { if (currentSession != null) { return currentSession.getOpponents(); } else { @@ -484,11 +474,12 @@ public void switchCamera(CameraVideoCapturer.CameraSwitchHandler cameraSwitchHan } public boolean isCameraFront() { - if (currentSession != null && currentSession.getMediaStreamManager() != null) { + try { QBRTCCameraVideoCapturer videoCapturer = (QBRTCCameraVideoCapturer) currentSession.getMediaStreamManager().getVideoCapturer(); return videoCapturer.getCameraName().contains("front"); + } catch (NullPointerException exception) { + return true; } - return true; } public void switchAudio() { @@ -544,19 +535,36 @@ public void removeCallTimerCallback() { } private void startCallTimer() { - if (callTime == null) { - callTime = 1000L; - } - if (!callTimerTask.isRunning()) { - callTimer.scheduleAtFixedRate(callTimerTask, 0, 1000L); - } + long INITIAL_DELAY_1_SECOND = 1; + long PERIOD_1_SECOND = 1; + + future = scheduledExecutorService.scheduleAtFixedRate(() -> { + callTime = callTime + 1L; + Notification notification = buildNotification(); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager != null) { + notificationManager.notify(SERVICE_ID, notification); + } + + if (callTimerListener != null) { + String callTime = modifyCallTimeToString(); + if (!TextUtils.isEmpty(callTime)) { + callTimerListener.onCallTimeUpdate(callTime); + } + } + }, + INITIAL_DELAY_1_SECOND, + PERIOD_1_SECOND, + TimeUnit.SECONDS); } private void stopCallTimer() { callTimerListener = null; - - callTimer.cancel(); - callTimer.purge(); + if (future != null) { + future.cancel(true); + future = null; + } + scheduledExecutorService.shutdownNow(); } public void clearButtonsState() { @@ -570,32 +578,6 @@ public void clearCallState() { SharedPrefsHelper.getInstance().delete(Consts.EXTRA_IS_INCOMING_CALL); } - private class CallTimerTask extends TimerTask { - private boolean isRunning = false; - - @Override - public void run() { - isRunning = true; - callTime = callTime + 1000L; - Notification notification = initNotification(); - NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - if (notificationManager != null) { - notificationManager.notify(SERVICE_ID, notification); - } - - if (callTimerListener != null) { - String callTime = getCallTime(); - if (!TextUtils.isEmpty(callTime)) { - callTimerListener.onCallTimeUpdate(callTime); - } - } - } - - public boolean isRunning() { - return isRunning; - } - } - public class CallServiceBinder extends Binder { public CallService getService() { return CallService.this; @@ -605,16 +587,13 @@ public CallService getService() { private class ConnectionListenerImpl extends AbstractConnectionListener { @Override public void connectionClosedOnError(Exception e) { - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - int reconnectHangUpTimeMillis = SettingsUtil.getPreferenceInt(sharedPref, - getApplicationContext(), R.string.pref_disconnect_time_interval_key, - R.string.pref_disconnect_time_interval_default_value) * 1000; - expirationReconnectionTime = System.currentTimeMillis() + reconnectHangUpTimeMillis; + int RECONNECT_HANG_UP_TIME_10_SECONDS = 10 * 1000; + expirationReconnectionTime = System.currentTimeMillis() + RECONNECT_HANG_UP_TIME_10_SECONDS; } @Override public void reconnectionSuccessful() { - + // empty } @Override @@ -654,7 +633,7 @@ public void onReceiveHangUpFromUser(QBRTCSession session, Integer userID, Map map) { stopRingtone(); - if (session != WebRtcSessionManager.getInstance(getApplicationContext()).getCurrentSession()) { - return; - } } @Override @@ -687,9 +663,9 @@ public void onUserNoActions(QBRTCSession qbrtcSession, Integer integer) { @Override public void onSessionClosed(QBRTCSession session) { - stopRingtone(); Log.d(TAG, "Session " + session.getSessionID() + " onSessionClosed()"); if (session == currentSession) { + stopRingtone(); Log.d(TAG, "Stopping Session"); CallService.stop(CallService.this); } @@ -697,17 +673,14 @@ public void onSessionClosed(QBRTCSession session) { @Override public void onCallRejectByUser(QBRTCSession session, Integer integer, Map map) { - stopRingtone(); - if (session == WebRtcSessionManager.getInstance(getApplicationContext()).getCurrentSession()) { - return; - } + // empty } } private class SessionStateListener implements QBRTCSessionStateCallback { @Override public void onStateChanged(QBRTCSession qbrtcSession, BaseSession.QBRTCSessionState qbrtcSessionState) { - + // empty } @Override @@ -715,7 +688,10 @@ public void onConnectedToUser(QBRTCSession qbrtcSession, Integer integer) { stopRingtone(); isCallState = true; Log.d(TAG, "onConnectedToUser() is started"); - startCallTimer(); + + if (future == null) { + startCallTimer(); + } } @Override @@ -736,7 +712,7 @@ public void onConnectionClosedForUser(QBRTCSession qbrtcSession, Integer userID) private class QBRTCSignalingListener implements QBRTCSignalingCallback { @Override public void onSuccessSendingPacket(QBSignalingSpec.QBSignalCMD qbSignalCMD, Integer integer) { - + // empty } @Override @@ -790,9 +766,9 @@ private class VideoTrackListener implements QBRTCClientVideoTracksCallbacks() { @Override diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/services/fcm/PushListenerService.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/services/fcm/PushListenerService.java index 5aa625365..f1d658196 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/services/fcm/PushListenerService.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/services/fcm/PushListenerService.java @@ -18,8 +18,8 @@ public class PushListenerService extends QBFcmPushListenerService { public void onMessageReceived(RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); SharedPrefsHelper sharedPrefsHelper = SharedPrefsHelper.getInstance(); - if (sharedPrefsHelper.hasQbUser()) { - QBUser qbUser = sharedPrefsHelper.getQbUser(); + if (sharedPrefsHelper.hasUser()) { + QBUser qbUser = sharedPrefsHelper.getUser(); Log.d(TAG, "App has logged user" + qbUser.getId()); LoginService.start(this, qbUser); } diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/util/ChatPingAlarmManager.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/util/ChatPingAlarmManager.java deleted file mode 100644 index e1438a3b9..000000000 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/util/ChatPingAlarmManager.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.quickblox.sample.videochat.java.util; - - -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Build; -import android.os.Bundle; -import android.os.SystemClock; -import android.util.Log; - -import com.quickblox.chat.QBChatService; -import com.quickblox.chat.QBPingManager; -import com.quickblox.core.QBEntityCallback; -import com.quickblox.core.exception.QBResponseException; - -import org.jivesoftware.smackx.ping.PingFailedListener; - -import java.util.concurrent.TimeUnit; - -public class ChatPingAlarmManager { - private static final String TAG = ChatPingAlarmManager.class.getSimpleName(); - - //Change interval for your behaviour - private static final String PING_ALARM_ACTION = "com.quickblox.chat.ping.ACTION"; - private static final long PING_INTERVAL = TimeUnit.SECONDS.toMillis(60); - - - private static final BroadcastReceiver ALARM_BROADCAST_RECEIVER = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - Log.v(TAG, "Ping Alarm broadcast received"); - - if (enabled) { - Log.d(TAG, "Calling pingServer for connection"); - final QBPingManager pingManager = QBChatService.getInstance().getPingManager(); - if (pingManager != null) { - pingManager.pingServer(new QBEntityCallback() { - @Override - public void onSuccess(Void result, Bundle params) { - } - - @Override - public void onError(QBResponseException responseException) { - if (pingFailedListener != null) { - pingFailedListener.pingFailed(); - } - } - }); - } - - } else { - Log.d(TAG, "NOT calling pingServerIfNecessary (disabled) on connection "); - } - } - }; - - private static Context sContext; - private static PendingIntent sPendingIntent; - private static AlarmManager sAlarmManager; - private static boolean enabled = true; - private static ChatPingAlarmManager instance; - private static PingFailedListener pingFailedListener; - - public static void setEnabled(boolean enabled) { - ChatPingAlarmManager.enabled = enabled; - } - - private ChatPingAlarmManager() { - } - - public void addPingListener(PingFailedListener pingFailedListener) { - this.pingFailedListener = pingFailedListener; - } - - public static synchronized ChatPingAlarmManager getInstanceFor() { - if (instance == null) { - instance = new ChatPingAlarmManager(); - } - return instance; - } - - /** - * Register a pending intent with the AlarmManager to be broadcasted every - * half hour and register the alarm broadcast receiver to receive this - * intent. The receiver will check all known questions if a ping is - * Necessary when invoked by the alarm intent. - * - * @param context - */ - public static void onCreate(Context context) { - sContext = context; - context.registerReceiver(ALARM_BROADCAST_RECEIVER, new IntentFilter(PING_ALARM_ACTION)); - sAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - - int intentFlag = 0; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - intentFlag = PendingIntent.FLAG_IMMUTABLE; - } - - sPendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(PING_ALARM_ACTION), intentFlag); - sAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + PING_INTERVAL, - PING_INTERVAL, sPendingIntent); - } - - /** - * Unregister the alarm broadcast receiver and cancel the alarm. - */ - public static void onDestroy() { - if (sContext != null) { - try { - sContext.unregisterReceiver(ALARM_BROADCAST_RECEIVER); - } catch (IllegalArgumentException ignored) { - Log.d (TAG, "Receiver not registered before"); - } - } - if (sAlarmManager != null) { - sAlarmManager.cancel(sPendingIntent); - } - pingFailedListener = null; - instance = null; - } -} \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/util/NetworkConnectionChecker.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/util/NetworkConnectionChecker.java index 2977f1b77..13bace24d 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/util/NetworkConnectionChecker.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/util/NetworkConnectionChecker.java @@ -15,7 +15,7 @@ public class NetworkConnectionChecker { private final ConnectivityManager connectivityManager; - private Set listeners = new CopyOnWriteArraySet<>(); + private final Set listeners = new CopyOnWriteArraySet<>(); public NetworkConnectionChecker(Application context) { this.connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); @@ -38,9 +38,7 @@ public boolean isConnectedNow() { } public interface OnConnectivityChangedListener { - void connectivityChanged(boolean availableNow); - } private class NetworkStateReceiver extends BroadcastReceiver { diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/util/QBResRequestExecutor.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/util/QBResRequestExecutor.java index 8f9d6590f..0f6feb46c 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/util/QBResRequestExecutor.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/util/QBResRequestExecutor.java @@ -1,20 +1,12 @@ package com.quickblox.sample.videochat.java.util; -import android.os.Bundle; - import com.quickblox.core.QBEntityCallback; -import com.quickblox.core.exception.QBResponseException; -import com.quickblox.core.request.GenericQueryRule; import com.quickblox.core.request.QBPagedRequestBuilder; -import com.quickblox.sample.videochat.java.utils.Consts; import com.quickblox.users.QBUsers; import com.quickblox.users.model.QBUser; import java.util.ArrayList; import java.util.Collection; -import java.util.LinkedList; -import java.util.List; - public class QBResRequestExecutor { private String TAG = QBResRequestExecutor.class.getSimpleName(); @@ -27,7 +19,7 @@ public void signInUser(final QBUser currentQbUser, final QBEntityCallback callback) { + public void signOut(QBEntityCallback callback) { QBUsers.signOut().performAsync(callback); } diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/Consts.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/Consts.java index a3353de79..66fc79bba 100755 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/Consts.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/Consts.java @@ -6,21 +6,11 @@ * QuickBlox team */ public interface Consts { - int ERR_LOGIN_ALREADY_TAKEN_HTTP_STATUS = 422; - int MAX_OPPONENTS_COUNT = 6; - int MAX_LOGIN_LENGTH = 15; - int MAX_FULLNAME_LENGTH = 20; - - String EXTRA_QB_USER = "qb_user"; - String EXTRA_USER_ID = "user_id"; - String EXTRA_USER_LOGIN = "user_login"; - String EXTRA_USER_PASSWORD = "user_password"; - String EXTRA_PENDING_INTENT = "pending_Intent"; - String EXTRA_CONTEXT = "context"; - String EXTRA_OPPONENTS_LIST = "opponents_list"; - String EXTRA_CONFERENCE_TYPE = "conference_type"; + int MAX_OPPONENTS_COUNT = 3; + int MAX_LOGIN_LENGTH = 50; + int MAX_DISPLAY_NAME_LENGTH = 20; String EXTRA_IS_INCOMING_CALL = "conversation_reason"; diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/DialogUtil.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/DialogUtil.java deleted file mode 100755 index f3368c014..000000000 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/DialogUtil.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.quickblox.sample.videochat.java.utils; - -import android.content.Context; -import android.widget.Toast; - -/** - * QuickBlox team - */ -public class DialogUtil { - - public static void showToast(Context context, String message) { - Toast.makeText(context, message, Toast.LENGTH_LONG).show(); - } - - public static void showToast(Context context, int messageId) { - Toast.makeText(context, context.getString(messageId), Toast.LENGTH_LONG).show(); - } -} \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/PushNotificationSender.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/PushNotificationSender.java index 79c5649bb..52c4b43b3 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/PushNotificationSender.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/PushNotificationSender.java @@ -10,39 +10,37 @@ import org.json.JSONException; import org.json.JSONObject; -import java.util.ArrayList; - public class PushNotificationSender { - public static void sendPushMessage(ArrayList recipients, String senderName, String newSessionID, - String opponentsIDs, String opponentsNames, boolean isVideoCall) { + public static void sendPushMessage(Integer recipientId, String senderName, String sessionId, + String opponentIds, String opponentNames, boolean isVideoCall) { String outMessage = String.format(String.valueOf(R.string.text_push_notification_message), senderName); long timeStamp = System.currentTimeMillis(); - // Send Push: create QuickBlox Push Notification Event - QBEvent qbEvent = new QBEvent(); - qbEvent.setNotificationType(QBNotificationType.PUSH); - qbEvent.setEnvironment(QBEnvironment.DEVELOPMENT); - // Generic push - will be delivered to all platforms (Android, iOS, WP, Blackberry..) + // send Push: create QuickBlox Push Notification Event + QBEvent event = new QBEvent(); + event.setNotificationType(QBNotificationType.PUSH); + event.setEnvironment(QBEnvironment.DEVELOPMENT); + // generic push - will be delivered to all platforms (Android, iOS, WP, Blackberry..) JSONObject json = new JSONObject(); try { json.put("message", outMessage); json.put("ios_voip", "1"); json.put("VOIPCall", "1"); - json.put("sessionID", newSessionID); - json.put("opponentsIDs", opponentsIDs); - json.put("contactIdentifier", opponentsNames); + json.put("sessionID", sessionId); + json.put("opponentsIDs", opponentIds); + json.put("contactIdentifier", opponentNames); json.put("conferenceType", isVideoCall ? "1" : "2"); json.put("timestamp", Long.toString(timeStamp)); } catch (JSONException e) { e.printStackTrace(); } - qbEvent.setMessage(json.toString()); - - StringifyArrayList userIds = new StringifyArrayList<>(recipients); - qbEvent.setUserIds(userIds); + event.setMessage(json.toString()); - QBPushNotifications.createEvent(qbEvent).performAsync(null); + StringifyArrayList userIds = new StringifyArrayList<>(); + userIds.add(recipientId); + event.setUserIds(userIds); + QBPushNotifications.createEvent(event).performAsync(null); } } \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/SettingsManager.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/SettingsManager.java new file mode 100755 index 000000000..b97a2fa74 --- /dev/null +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/SettingsManager.java @@ -0,0 +1,44 @@ +package com.quickblox.sample.videochat.java.utils; + +import com.quickblox.videochat.webrtc.QBRTCConfig; +import com.quickblox.videochat.webrtc.QBRTCMediaConfig; + +import static com.quickblox.sample.videochat.java.utils.Consts.MAX_OPPONENTS_COUNT; + +/** + * QuickBlox team + */ +public class SettingsManager { + public static void applySettings() { + applyCallSettings(); + applyVideoSettings(); + } + + private static void applyCallSettings() { + QBRTCMediaConfig.setAudioCodec(QBRTCMediaConfig.AudioCodec.ISAC); + QBRTCMediaConfig.setUseBuildInAEC(true); + QBRTCMediaConfig.setAudioProcessingEnabled(true); + QBRTCMediaConfig.setUseOpenSLES(false); + } + + private static void applyVideoSettings() { + QBRTCMediaConfig.setVideoHWAcceleration(true); + QBRTCMediaConfig.setVideoWidth(QBRTCMediaConfig.VideoQuality.VGA_VIDEO.width); + QBRTCMediaConfig.setVideoHeight(QBRTCMediaConfig.VideoQuality.VGA_VIDEO.height); + QBRTCMediaConfig.setVideoCodec(QBRTCMediaConfig.VideoCodec.VP8); + } + + public static void applyRTCSettings() { + QBRTCConfig.setMaxOpponentsCount(MAX_OPPONENTS_COUNT); + QBRTCConfig.setDebugEnabled(true); + + int ANSWER_TIME_INTERVAL = 30; + QBRTCConfig.setAnswerTimeInterval(ANSWER_TIME_INTERVAL); + + int DISCONNECT_TIME_10_SECONDS = 10; + QBRTCConfig.setDisconnectTime(DISCONNECT_TIME_10_SECONDS); + + int DIALING_TIME_INTERVAL = 5; + QBRTCConfig.setDialingTimeInterval(DIALING_TIME_INTERVAL); + } +} \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/SettingsUtil.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/SettingsUtil.java deleted file mode 100755 index 5c18ecd3b..000000000 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/SettingsUtil.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.quickblox.sample.videochat.java.utils; - -import android.content.Context; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import android.util.Log; - -import com.quickblox.sample.videochat.java.R; -import com.quickblox.videochat.webrtc.QBRTCConfig; -import com.quickblox.videochat.webrtc.QBRTCMediaConfig; - -import java.util.List; - -/** - * QuickBlox team - */ -public class SettingsUtil { - - private static final String TAG = SettingsUtil.class.getSimpleName(); - - private static void setSettingsForMultiCall(List users) { - if (users.size() <= 4) { - setDefaultVideoQuality(); - } else { - //set to minimum settings - QBRTCMediaConfig.setVideoWidth(QBRTCMediaConfig.VideoQuality.QBGA_VIDEO.width); - QBRTCMediaConfig.setVideoHeight(QBRTCMediaConfig.VideoQuality.QBGA_VIDEO.height); - QBRTCMediaConfig.setVideoHWAcceleration(false); - QBRTCMediaConfig.setVideoCodec(null); - } - } - - public static void setSettingsStrategy(List users, SharedPreferences sharedPref, Context context) { - setCommonSettings(sharedPref, context); - if (users.size() == 1) { - setSettingsFromPreferences(sharedPref, context); - } else { - setSettingsForMultiCall(users); - } - } - - private static void setCommonSettings(SharedPreferences sharedPref, Context context) { - String audioCodecDescription = getPreferenceString(sharedPref, context, R.string.pref_audiocodec_key, - R.string.pref_audiocodec_def); - QBRTCMediaConfig.AudioCodec audioCodec = QBRTCMediaConfig.AudioCodec.ISAC.getDescription() - .equals(audioCodecDescription) ? - QBRTCMediaConfig.AudioCodec.ISAC : QBRTCMediaConfig.AudioCodec.OPUS; - Log.e(TAG, "audioCodec =: " + audioCodec.getDescription()); - QBRTCMediaConfig.setAudioCodec(audioCodec); - Log.v(TAG, "audioCodec = " + QBRTCMediaConfig.getAudioCodec()); - // Check Disable built-in AEC flag. - boolean disableBuiltInAEC = getPreferenceBoolean(sharedPref, context, - R.string.pref_disable_built_in_aec_key, - R.string.pref_disable_built_in_aec_default); - - QBRTCMediaConfig.setUseBuildInAEC(!disableBuiltInAEC); - Log.v(TAG, "setUseBuildInAEC = " + QBRTCMediaConfig.isUseBuildInAEC()); - // Check Disable Audio Processing flag. - boolean noAudioProcessing = getPreferenceBoolean(sharedPref, context, - R.string.pref_noaudioprocessing_key, - R.string.pref_noaudioprocessing_default); - QBRTCMediaConfig.setAudioProcessingEnabled(!noAudioProcessing); - Log.v(TAG, "isAudioProcessingEnabled = " + QBRTCMediaConfig.isAudioProcessingEnabled()); - // Check OpenSL ES enabled flag. - boolean useOpenSLES = getPreferenceBoolean(sharedPref, context, - R.string.pref_opensles_key, - R.string.pref_opensles_default); - QBRTCMediaConfig.setUseOpenSLES(useOpenSLES); - Log.v(TAG, "isUseOpenSLES = " + QBRTCMediaConfig.isUseOpenSLES()); - } - - private static void setSettingsFromPreferences(SharedPreferences sharedPref, Context context) { - - // Check HW codec flag. - boolean hwCodec = sharedPref.getBoolean(context.getString(R.string.pref_hwcodec_key), - Boolean.valueOf(context.getString(R.string.pref_hwcodec_default))); - - QBRTCMediaConfig.setVideoHWAcceleration(hwCodec); - - // Get video resolution from settings. - int resolutionItem = Integer.parseInt(sharedPref.getString(context.getString(R.string.pref_resolution_key), - "0")); - Log.e(TAG, "resolutionItem =: " + resolutionItem); - setVideoQuality(resolutionItem); - Log.v(TAG, "resolution = " + QBRTCMediaConfig.getVideoHeight() + "x" + QBRTCMediaConfig.getVideoWidth()); - - // Get start bitrate. - int startBitrate = getPreferenceInt(sharedPref, context, - R.string.pref_startbitratevalue_key, - R.string.pref_startbitratevalue_default); - Log.e(TAG, "videoStartBitrate =: " + startBitrate); - QBRTCMediaConfig.setVideoStartBitrate(startBitrate); - Log.v(TAG, "videoStartBitrate = " + QBRTCMediaConfig.getVideoStartBitrate()); - - int videoCodecItem = Integer.parseInt(getPreferenceString(sharedPref, context, R.string.pref_videocodec_key, "0")); - for (QBRTCMediaConfig.VideoCodec codec : QBRTCMediaConfig.VideoCodec.values()) { - if (codec.ordinal() == videoCodecItem) { - Log.e(TAG, "videoCodecItem =: " + codec.getDescription()); - QBRTCMediaConfig.setVideoCodec(codec); - Log.v(TAG, "videoCodecItem = " + QBRTCMediaConfig.getVideoCodec()); - break; - } - } - // Get camera fps from settings. - int cameraFps = getPreferenceInt(sharedPref, context, R.string.pref_frame_rate_key, R.string.pref_frame_rate_default); - Log.e(TAG, "cameraFps = " + cameraFps); - QBRTCMediaConfig.setVideoFps(cameraFps); - Log.v(TAG, "cameraFps = " + QBRTCMediaConfig.getVideoFps()); - } - - public static void configRTCTimers(Context context) { - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); - - long answerTimeInterval = getPreferenceInt(sharedPref, context, - R.string.pref_answer_time_interval_key, - R.string.pref_answer_time_interval_default_value); - QBRTCConfig.setAnswerTimeInterval(answerTimeInterval); - Log.e(TAG, "answerTimeInterval = " + answerTimeInterval); - - int disconnectTimeInterval = getPreferenceInt(sharedPref, context, - R.string.pref_disconnect_time_interval_key, - R.string.pref_disconnect_time_interval_default_value); - QBRTCConfig.setDisconnectTime(disconnectTimeInterval); - Log.e(TAG, "disconnectTimeInterval = " + disconnectTimeInterval); - - long dialingTimeInterval = getPreferenceInt(sharedPref, context, - R.string.pref_dialing_time_interval_key, - R.string.pref_dialing_time_interval_default_value); - QBRTCConfig.setDialingTimeInterval(dialingTimeInterval); - Log.e(TAG, "dialingTimeInterval = " + dialingTimeInterval); - } - - public static boolean isManageSpeakerPhoneByProximity(Context context) { - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); - boolean manageSpeakerPhoneByProximity = sharedPref.getBoolean(context.getString(R.string.pref_manage_speakerphone_by_proximity_key), - Boolean.valueOf(context.getString(R.string.pref_manage_speakerphone_by_proximity_default))); - - return manageSpeakerPhoneByProximity; - } - - private static void setVideoQuality(int resolutionItem) { - if (resolutionItem != -1) { - setVideoFromLibraryPreferences(resolutionItem); - } else { - setDefaultVideoQuality(); - } - } - - private static void setDefaultVideoQuality() { - QBRTCMediaConfig.setVideoWidth(QBRTCMediaConfig.VideoQuality.VGA_VIDEO.width); - QBRTCMediaConfig.setVideoHeight(QBRTCMediaConfig.VideoQuality.VGA_VIDEO.height); - } - - private static void setVideoFromLibraryPreferences(int resolutionItem) { - for (QBRTCMediaConfig.VideoQuality quality : QBRTCMediaConfig.VideoQuality.values()) { - if (quality.ordinal() == resolutionItem) { - Log.e(TAG, "resolution =: " + quality.height + ":" + quality.width); - QBRTCMediaConfig.setVideoHeight(quality.height); - QBRTCMediaConfig.setVideoWidth(quality.width); - } - } - } - - private static String getPreferenceString(SharedPreferences sharedPref, Context context, int strResKey, int strResDefValue) { - return sharedPref.getString(context.getString(strResKey), context.getString(strResDefValue)); - } - - private static String getPreferenceString(SharedPreferences sharedPref, Context context, int strResKey, String strResDefValue) { - return sharedPref.getString(context.getString(strResKey), strResDefValue); - } - - public static int getPreferenceInt(SharedPreferences sharedPref, Context context, int strResKey, int strResDefValue) { - return sharedPref.getInt(context.getString(strResKey), Integer.valueOf(context.getString(strResDefValue))); - } - - private static boolean getPreferenceBoolean(SharedPreferences sharedPref, Context context, int StrRes, int strResDefValue) { - return sharedPref.getBoolean(context.getString(StrRes), Boolean.valueOf(context.getString(strResDefValue))); - } -} \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/SharedPrefsHelper.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/SharedPrefsHelper.java index a2cf6d6a3..7028c9e16 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/SharedPrefsHelper.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/SharedPrefsHelper.java @@ -17,7 +17,7 @@ public class SharedPrefsHelper { private static final String QB_USER_TAGS = "qb_user_tags"; private static SharedPrefsHelper instance; - private SharedPreferences sharedPreferences; + private final SharedPreferences sharedPreferences; public static synchronized SharedPrefsHelper getInstance() { if (instance == null) { @@ -73,7 +73,7 @@ private boolean has(String key) { return sharedPreferences.contains(key); } - public void saveQbUser(QBUser qbUser) { + public void saveUser(QBUser qbUser) { save(QB_USER_ID, qbUser.getId()); save(QB_USER_LOGIN, qbUser.getLogin()); save(QB_USER_PASSWORD, qbUser.getPassword()); @@ -81,7 +81,7 @@ public void saveQbUser(QBUser qbUser) { save(QB_USER_TAGS, qbUser.getTags().getItemsAsString()); } - public void removeQbUser() { + public void removeUser() { delete(QB_USER_ID); delete(QB_USER_LOGIN); delete(QB_USER_PASSWORD); @@ -89,8 +89,8 @@ public void removeQbUser() { delete(QB_USER_TAGS); } - public QBUser getQbUser() { - if (hasQbUser()) { + public QBUser getUser() { + if (hasUser()) { Integer id = get(QB_USER_ID); String login = get(QB_USER_LOGIN); String password = get(QB_USER_PASSWORD); @@ -114,7 +114,7 @@ public QBUser getQbUser() { } } - public boolean hasQbUser() { + public boolean hasUser() { return has(QB_USER_LOGIN) && has(QB_USER_PASSWORD); } diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/UsersUtils.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/UsersUtils.java index d36a0e23f..083e98364 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/UsersUtils.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/UsersUtils.java @@ -1,30 +1,26 @@ package com.quickblox.sample.videochat.java.utils; -import android.content.Context; - -import com.quickblox.sample.videochat.java.db.QbUsersDbManager; +import com.quickblox.sample.videochat.java.db.UsersDbManager; import com.quickblox.users.model.QBUser; import java.util.ArrayList; import java.util.List; - public class UsersUtils { - private static SharedPrefsHelper sharedPrefsHelper; - private static QbUsersDbManager dbManager; + private static UsersDbManager dbManager; - public static ArrayList getListAllUsersFromIds(ArrayList existedUsers, List allIds) { - ArrayList qbUsers = new ArrayList<>(); + public static ArrayList getUsersFromIds(ArrayList existedUsers, List allIds) { + ArrayList users = new ArrayList<>(); for (Integer userId : allIds) { QBUser stubUser = createStubUserById(userId); if (!existedUsers.contains(stubUser)) { - qbUsers.add(stubUser); + users.add(stubUser); } } - qbUsers.addAll(existedUsers); + users.addAll(existedUsers); - return qbUsers; + return users; } private static QBUser createStubUserById(Integer userId) { @@ -45,13 +41,13 @@ public static ArrayList getIdsNotLoadedUsers(ArrayList existedU return idsNotLoadedUsers; } - public static void removeUserData(Context context) { + public static void removeUserData() { if (sharedPrefsHelper == null) { sharedPrefsHelper = SharedPrefsHelper.getInstance(); } sharedPrefsHelper.clearAllData(); if (dbManager == null) { - dbManager = QbUsersDbManager.getInstance(context); + dbManager = UsersDbManager.getInstance(); } dbManager.clearDB(); } diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/ValidationUtils.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/ValidationUtils.java index 4cc0fc062..bd88ce769 100644 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/ValidationUtils.java +++ b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/utils/ValidationUtils.java @@ -1,46 +1,34 @@ package com.quickblox.sample.videochat.java.utils; -import android.content.Context; import android.text.TextUtils; -import android.widget.EditText; - -import com.quickblox.sample.videochat.java.R; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class ValidationUtils { +import static com.quickblox.sample.videochat.java.utils.Consts.MAX_DISPLAY_NAME_LENGTH; +import static com.quickblox.sample.videochat.java.utils.Consts.MAX_LOGIN_LENGTH; +public class ValidationUtils { private ValidationUtils() { - } - private static boolean isEnteredTextValid(Context context, EditText editText, int resFieldName, int maxLength, boolean checkLogin) { + private static boolean checkTextByPattern(String text, Pattern pattern) { boolean isCorrect = false; - Pattern pattern; - if (checkLogin) { - pattern = Pattern.compile("^[a-zA-Z][a-zA-Z0-9]{2," + (maxLength - 1) + "}+$"); - } else { - pattern = Pattern.compile("^[a-zA-Z][a-zA-Z 0-9]{2," + (maxLength - 1) + "}+$"); - } - if (!TextUtils.isEmpty(editText.getText().toString())) { - Matcher matcher = pattern.matcher(editText.getText().toString().trim()); + if (!TextUtils.isEmpty(text)) { + Matcher matcher = pattern.matcher(text.trim()); isCorrect = matcher.matches(); } - - if (!isCorrect) { - editText.setError(String.format(context.getString(R.string.error_name_must_not_contain_special_characters_from_app), context.getString(resFieldName), String.valueOf(maxLength))); - } - return isCorrect; } - public static boolean isLoginValid(Context context, EditText editText) { - return isEnteredTextValid(context, editText, R.string.field_name_user_login, Consts.MAX_LOGIN_LENGTH, true); + public static boolean isDisplayNameValid(String displayName) { + Pattern pattern = Pattern.compile("^[a-zA-Z][a-zA-Z 0-9]{2," + (MAX_DISPLAY_NAME_LENGTH - 1) + "}+$"); + return checkTextByPattern(displayName, pattern); } - public static boolean isFoolNameValid(Context context, EditText editText) { - return isEnteredTextValid(context, editText, R.string.field_name_user_fullname, Consts.MAX_FULLNAME_LENGTH, false); + public static boolean isLoginValid(String login) { + Pattern pattern = Pattern.compile("^[a-zA-Z][a-zA-Z0-9]{2," + (MAX_LOGIN_LENGTH - 1) + "}+$"); + return checkTextByPattern(login, pattern); } } \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/view/ListPreferenceCompat.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/view/ListPreferenceCompat.java deleted file mode 100644 index b9aa1a81f..000000000 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/view/ListPreferenceCompat.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.quickblox.sample.videochat.java.view; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build; -import android.preference.ListPreference; -import android.text.TextUtils; -import android.util.AttributeSet; - -public class ListPreferenceCompat extends ListPreference { - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public ListPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public ListPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public ListPreferenceCompat(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public ListPreferenceCompat(Context context) { - super(context); - } - - @Override - public void setValue(String value) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - super.setValue(value); - } else { - String oldValue = getValue(); - super.setValue(value); - if (!TextUtils.equals(value, oldValue)) { - notifyChanged(); - } - } - } -} \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/view/SeekBarPreference.java b/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/view/SeekBarPreference.java deleted file mode 100644 index e0f34d95a..000000000 --- a/sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/view/SeekBarPreference.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.quickblox.sample.videochat.java.view; - -import android.content.Context; -import android.content.res.TypedArray; -import android.preference.Preference; -import android.util.AttributeSet; -import android.util.Log; -import android.view.View; -import android.widget.SeekBar; - -import com.quickblox.sample.videochat.java.R; - -public class SeekBarPreference extends Preference implements SeekBar.OnSeekBarChangeListener { - - private static final String ANDROID_NS = "http://schemas.android.com/apk/res/android"; - private static final String SEEKBAR_NS = "http://schemas.android.com/apk/res-auto"; - - - private Context context; - private SeekBar seekBar; - private int progress, maxSeekBarValue, minSeekBarValue, seekBarStepSize; - - public SeekBarPreference(Context context) { - this(context, null, 0); - } - - public SeekBarPreference(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public SeekBarPreference(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setLayoutResource(R.layout.seekbar_preference); - - this.context = context; - - initFields(context, attrs); - } - - private void initFields(Context context, AttributeSet attrs) { - int maxValueResourceId = attrs.getAttributeResourceValue(ANDROID_NS, "max", R.integer.pref_default_int_value); - maxSeekBarValue = context.getResources().getInteger(maxValueResourceId); - - int minValueResourceId = attrs.getAttributeResourceValue(SEEKBAR_NS, "min", R.integer.pref_default_int_value); - minSeekBarValue = context.getResources().getInteger(minValueResourceId); - - int stepSizeValueResourceId = attrs.getAttributeResourceValue(SEEKBAR_NS, "stepSize", R.integer.pref_default_int_value); - seekBarStepSize = context.getResources().getInteger(stepSizeValueResourceId); - - Log.v("Attribute", "max = " + maxSeekBarValue); - Log.v("Attribute", "min = " + minSeekBarValue); - Log.v("Attribute", "step = " + seekBarStepSize); - } - - @Override - protected void onBindView(View view) { - super.onBindView(view); - seekBar = (SeekBar) view.findViewById(R.id.seekbar); - seekBar.setMax(maxSeekBarValue); - seekBar.setProgress(progress); - seekBar.setOnSeekBarChangeListener(this); - } - - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (!fromUser) - return; - - progress = (progress / seekBarStepSize) * seekBarStepSize; - - if (progress <= minSeekBarValue) { - progress = minSeekBarValue + progress; - } - - setValue(progress); - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - // not used - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - // not used - } - - @Override - protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { - setValue(restoreValue ? getPersistedInt(progress) : (Integer) defaultValue); - } - - public void setValue(int value) { - if (shouldPersist()) { - persistInt(value); - } - - if (value != progress) { - progress = value; - notifyChanged(); - } - - setSummary(String.valueOf(progress)); - } - - @Override - protected Object onGetDefaultValue(TypedArray a, int index) { - return a.getInt(index, 0); - } -} \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/res/drawable/ic_qb_logo.xml b/sample-videochat-java/app/src/main/res/drawable/ic_qb_logo.xml new file mode 100644 index 000000000..1c3168ea7 --- /dev/null +++ b/sample-videochat-java/app/src/main/res/drawable/ic_qb_logo.xml @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/res/layout/activity_login.xml b/sample-videochat-java/app/src/main/res/layout/activity_login.xml index 3ec404b86..1972b66e9 100644 --- a/sample-videochat-java/app/src/main/res/layout/activity_login.xml +++ b/sample-videochat-java/app/src/main/res/layout/activity_login.xml @@ -19,9 +19,9 @@ android:textSize="16sp" /> diff --git a/sample-videochat-java/app/src/main/res/layout/fragment_video_conversation.xml b/sample-videochat-java/app/src/main/res/layout/fragment_video_conversation.xml index 1dc6ba255..3c1efec9f 100755 --- a/sample-videochat-java/app/src/main/res/layout/fragment_video_conversation.xml +++ b/sample-videochat-java/app/src/main/res/layout/fragment_video_conversation.xml @@ -11,25 +11,44 @@ android:layout_height="wrap_content" android:layout_above="@+id/grid_opponents" /> - + + + + + + + android:textSize="18sp" + android:textStyle="normal|bold" /> - + - + android:layout_alignParentTop="true" /> - - - + - - + - \ No newline at end of file + diff --git a/sample-videochat-java/app/src/main/res/layout/toolbar_call.xml b/sample-videochat-java/app/src/main/res/layout/toolbar_call.xml index 969bc33db..9c7121155 100644 --- a/sample-videochat-java/app/src/main/res/layout/toolbar_call.xml +++ b/sample-videochat-java/app/src/main/res/layout/toolbar_call.xml @@ -4,7 +4,7 @@ android:layout_height="wrap_content" android:orientation="vertical"> - - + app:showAsAction="never" /> \ No newline at end of file diff --git a/sample-videochat-java/app/src/main/res/values/strings.xml b/sample-videochat-java/app/src/main/res/values/strings.xml index cebb036b0..5f117972f 100755 --- a/sample-videochat-java/app/src/main/res/values/strings.xml +++ b/sample-videochat-java/app/src/main/res/values/strings.xml @@ -54,10 +54,8 @@ %s is not available now! - User name - User Full Name - - %1$s must contain 3 — %2$s alphanumeric Latin characters without spaces, the first char must be a letter + Use your email or alphanumeric characters in a range from 3 to 50. First character must be a letter. + Use alphanumeric characters and spaces in a range from 3 to 20. Cannot contain more than one space in a row. Done @@ -100,9 +98,9 @@ Time Out Failed - Please enter Login and Username. + Please enter Login and Display Name. Login - Username + Display Name Select users you want to call @@ -111,121 +109,14 @@ "%s is calling you" - - Video - Call Settings - - Default - 0 - - default_camera_preference - Default Camera - Select default camera - 0 - - frame_rate - Frame Rate (0–30) - 0 - 0 - 30 - 5 - - resolution_preference - Video Format - Enter RTC local video resolution - -1 - - startbitrate_preference - Start bitrate setting - Start bitrate setting - Default - - startbitratevalue_preference - Bandwidth (0–2000) - 0 - 0 - 2000 - 100 - - disable_built_in_aec_preference - Disable built-in AEC - Disable built-in AEC - false - Built-in AEC is not available - - opensles_preference - Use OpenSL ES for audio playback - Use OpenSL ES for audio playback - false - - audioprocessing_preference - Disable audio processing - Disable audio processing pipeline - false - - manage_speakerphone_by_proximity_preference - Manage Speaker Phone by Proximity Sensor - Manage Speaker Phone by Proximity Sensor - Enables managing of Speaker Phone by Proximity Sensor for Audio calls - false - - - answer_time_interval - Answer Time Interval (15–90s) - 30 - 15 - 90 - 5 - - disconnect_time_interval - Disconnect Time Interval (10–90s) - 10 - 10 - 90 - 5 - - Dialing_time_interval - Dialing Time Interval (3–10s) - 5 - 3 - 10 - 1 - - videocodec_preference - Default video codec - Select default video codec - 0 - - hwcodec_preference - Video codec hardware acceleration - true - - Enabled - Disabled - - room_server_url_preference - Room server URL. - Enter a room server URL. - https://apprtc.appspot.com - - displayhud_preference - Display call statistics. - Display call statistics. - false - pref_audio_codec - Default audio codec - ISAC - Select default audio codec - QuickBlox WebRTC\nBuild version 1.12 - screenShot Accepted Connection was lost - and %s other and %s Ringing Stop \"Failed switch camera\" + You Application version: diff --git a/sample-videochat-java/app/src/main/res/xml/preferences.xml b/sample-videochat-java/app/src/main/res/xml/preferences.xml deleted file mode 100755 index 34d4c3d76..000000000 --- a/sample-videochat-java/app/src/main/res/xml/preferences.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/sample-videochat-java/artifacts.gradle b/sample-videochat-java/artifacts.gradle index 95d0ba8e5..445174617 100644 --- a/sample-videochat-java/artifacts.gradle +++ b/sample-videochat-java/artifacts.gradle @@ -1,13 +1,5 @@ android.applicationVariants.all { variant -> - def appName - //Check if an applicationName property is supplied; if not use the name of the parent project. - if (project.hasProperty("applicationName")) { - appName = applicationName - } else { - appName = project.projectDir.getName() - } - variant.outputs.each { output -> def newApkName @@ -18,13 +10,13 @@ android.applicationVariants.all { } else { apkEndName = "-unaligned.apk" } - newApkName = "${appName}-${variant.buildType.name}-${getDate()}-code-${variant.versionCode}-version-${variant.versionName}-java" + apkEndName + newApkName = "videochat-java-${variant.buildType.name}-${getDate()}-version-${variant.versionName}" + apkEndName output.outputFileName = newApkName } } def getDate() { def date = new Date() - def formattedDate = date.format('yyyyMMdd') + def formattedDate = date.format('yyyy.MM.dd') return formattedDate } \ No newline at end of file diff --git a/sample-videochat-java/build.gradle b/sample-videochat-java/build.gradle index a29dafa35..370971703 100644 --- a/sample-videochat-java/build.gradle +++ b/sample-videochat-java/build.gradle @@ -6,7 +6,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:4.2.2' - classpath 'com.google.gms:google-services:4.3.10' + classpath 'com.google.gms:google-services:4.3.13' } } @@ -15,25 +15,4 @@ allprojects { google() mavenCentral() } -} - -ext { - dimensionDefault = 'default' - - lintAbortOnError = false - - // QuickBlox SDK version - qbSdkVersion = '3.9.15' - - //Firebase - firebaseCoreVersion = '21.0.0' - - //Material - materialVersion = '1.6.0' - - //RobotoTextView - robotoTextViewVersion = '4.0.0' - - //Pull to refresh - pullToRefreshVersion = '3.2.3' } \ No newline at end of file