diff --git a/ACKNOWLEDGEMENTS.md b/ACKNOWLEDGEMENTS.md index d3776f0d8..46ed3e18a 100644 --- a/ACKNOWLEDGEMENTS.md +++ b/ACKNOWLEDGEMENTS.md @@ -1,7 +1,7 @@ # Acknowledgements This software includes the following software dependencies under their corresponding licenses: - + - Twilio Video Android - https://www.twilio.com/legal/tos. - Generic [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0.txt). diff --git a/CHANGELOG.md b/CHANGELOG.md index 076210cdb..b957367ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -#### 0.1.0 +#### 0.1.0 -This is the initial release of this application as an open source project. The full release -to the Google Play Store will be part of the first major release. \ No newline at end of file +This is the initial release of this application as an open source project. The full release +to the Google Play Store will be part of the first major release. diff --git a/README.md b/README.md index ee7907285..e76db23b4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This project demonstrates a multi-party voice and video application built with the Twilio Android Video SDK. # Setup -Before running the app, follow the steps below to provide an access token required to connect to a Twilio room. +Before running the app, follow the steps below to provide an access token required to connect to a Twilio room. 1. Ensure you are using the community build variant. @@ -12,9 +12,9 @@ Before running the app, follow the steps below to provide an access token requir 3. Type in an identity and click on "Generate Access Token" from the [Testing Tools Page](https://www.twilio.com/console/video/runtime/testing-tools). -4. Add the access token string copied from the console to a variable named `TWILIO_ACCESS_TOKEN` +4. Add the access token string copied from the console to a variable named `TWILIO_ACCESS_TOKEN` in your **local.properties** file. ``` TWILIO_ACCESS_TOKEN=abcdef0123456789 -``` \ No newline at end of file +``` diff --git a/app/build.gradle b/app/build.gradle index 1ec2e00bc..d99b0c245 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,8 +4,8 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { - compileSdkVersion versions.compileSdk - buildToolsVersion "${versions.buildTools}" + compileSdkVersion 28 + buildToolsVersion '28.0.3' lintOptions { warningsAsErrors true @@ -20,8 +20,8 @@ android { defaultConfig { applicationId "com.twilio.video.app" - minSdkVersion versions.minSdk - targetSdkVersion versions.targetSdk + minSdkVersion 16 + targetSdkVersion 28 versionName "0.1.0" versionCode 1 @@ -32,8 +32,8 @@ android { } compileOptions { - sourceCompatibility versions.java - targetCompatibility versions.java + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } signingConfigs { @@ -104,43 +104,43 @@ android { dependencies { def butterknife = '10.2.0' + def dagger = '2.15' + def retrofit = '2.1.0' implementation 'com.twilio:twilio-android-env:1.0.0' implementation "com.twilio:video-android:5.0.0" implementation "androidx.constraintlayout:constraintlayout:1.1.3" implementation 'com.google.android.material:material:1.0.0' implementation 'androidx.legacy:legacy-preference-v14:1.0.0' implementation 'com.jakewharton.timber:timber:4.7.1' - implementation "com.appyvet:materialrangebar:${versions.materialrangebar}" + implementation "com.appyvet:materialrangebar:1.3" implementation "com.jakewharton:butterknife:$butterknife" - implementation "com.google.guava:guava:${versions.guava}" implementation 'androidx.multidex:multidex:2.0.1' - implementation "com.google.firebase:firebase-core:${versions.firebase}" - implementation "com.google.firebase:firebase-auth:${versions.firebaseAuth}" - implementation "com.crashlytics.sdk.android:crashlytics:${versions.crashlytics}" - implementation "com.google.android.gms:play-services-auth:${versions.playServicesAuth}" + implementation "com.google.firebase:firebase-core:16.0.1" + implementation "com.google.firebase:firebase-auth:16.0.2" + implementation "com.crashlytics.sdk.android:crashlytics:2.10.1" + implementation "com.google.android.gms:play-services-auth:15.0.1" - implementation "com.google.dagger:dagger:${versions.dagger}" - implementation "com.google.dagger:dagger-android:${versions.dagger}" - annotationProcessor "com.google.dagger:dagger-compiler:${versions.dagger}" + implementation "com.google.dagger:dagger:$dagger" + implementation "com.google.dagger:dagger-android:$dagger" + annotationProcessor "com.google.dagger:dagger-compiler:$dagger" - implementation "io.reactivex.rxjava2:rxjava:${versions.rxJava2}" - implementation "io.reactivex.rxjava2:rxandroid:${versions.rxAndroid2}" + implementation "io.reactivex.rxjava2:rxjava:2.2.10" + implementation "io.reactivex.rxjava2:rxandroid:2.1.1" - implementation "com.squareup.retrofit2:retrofit:${versions.retrofit2}" - implementation "com.squareup.retrofit2:converter-gson:${versions.retrofit2}" - implementation "com.squareup.retrofit2:converter-scalars:${versions.retrofit2}" + implementation "com.squareup.retrofit2:retrofit:$retrofit" + implementation "com.squareup.retrofit2:converter-gson:$retrofit" + implementation "com.squareup.retrofit2:converter-scalars:$retrofit" - implementation "com.jakewharton.retrofit:retrofit2-rxjava2-adapter:${versions.rxJava2Adapter}" + implementation "com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0" annotationProcessor "com.jakewharton:butterknife-compiler:$butterknife" } def getLocalProperty(key) { - def value = null if (project.rootProject.file('local.properties').exists()) { Properties properties = new Properties() properties.load(project.rootProject.file('local.properties').newDataInputStream()) - value = properties.getProperty(key) + def value = properties.getProperty(key) return value } else { logger.log(LogLevel.WARN, "Could not find local.properties in " + diff --git a/app/src/androidTest/java/com/twilio/video/app/ApplicationTest.java b/app/src/androidTest/java/com/twilio/video/app/ApplicationTest.java deleted file mode 100644 index c3e2ba9b4..000000000 --- a/app/src/androidTest/java/com/twilio/video/app/ApplicationTest.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2017 Twilio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twilio.video.app; - -import android.app.Application; -import android.test.ApplicationTestCase; - -/** Testing Fundamentals */ -public class ApplicationTest extends ApplicationTestCase { - public ApplicationTest() { - super(Application.class); - } -} diff --git a/app/src/community/java/com/twilio/video/app/CommunityTreeModule.java b/app/src/community/java/com/twilio/video/app/CommunityTreeModule.java index 2620e5227..5699646c7 100644 --- a/app/src/community/java/com/twilio/video/app/CommunityTreeModule.java +++ b/app/src/community/java/com/twilio/video/app/CommunityTreeModule.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2019 Twilio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.twilio.video.app; import com.twilio.video.LogLevel; diff --git a/app/src/community/java/com/twilio/video/app/VideoApplicationComponent.java b/app/src/community/java/com/twilio/video/app/VideoApplicationComponent.java index 465fa57d8..440c6dec2 100644 --- a/app/src/community/java/com/twilio/video/app/VideoApplicationComponent.java +++ b/app/src/community/java/com/twilio/video/app/VideoApplicationComponent.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2019 Twilio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.twilio.video.app; import com.twilio.video.app.auth.CommunityAuthModule; diff --git a/app/src/community/java/com/twilio/video/app/auth/CommunityAuthModule.java b/app/src/community/java/com/twilio/video/app/auth/CommunityAuthModule.java index e813a91f3..e4fce1434 100644 --- a/app/src/community/java/com/twilio/video/app/auth/CommunityAuthModule.java +++ b/app/src/community/java/com/twilio/video/app/auth/CommunityAuthModule.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2019 Twilio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.twilio.video.app.auth; import android.content.SharedPreferences; diff --git a/app/src/community/java/com/twilio/video/app/auth/CommunityAuthenticator.java b/app/src/community/java/com/twilio/video/app/auth/CommunityAuthenticator.java deleted file mode 100644 index 7f74ff500..000000000 --- a/app/src/community/java/com/twilio/video/app/auth/CommunityAuthenticator.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.twilio.video.app.auth; - -import android.content.SharedPreferences; -import com.google.common.base.Strings; -import com.twilio.video.app.base.BaseActivity; -import com.twilio.video.app.data.Preferences; -import com.twilio.video.app.ui.login.CommunityLoginActivity; - -public class CommunityAuthenticator implements Authenticator { - private final SharedPreferences preferences; - - public CommunityAuthenticator(SharedPreferences preferences) { - this.preferences = preferences; - } - - @Override - public Class getLoginActivity() { - return CommunityLoginActivity.class; - } - - @Override - public boolean loggedIn() { - return !Strings.isNullOrEmpty(preferences.getString(Preferences.DISPLAY_NAME, null)); - } - - @Override - public void logout() { - preferences.edit().remove(Preferences.DISPLAY_NAME).apply(); - } -} diff --git a/app/src/community/java/com/twilio/video/app/auth/CommunityAuthenticator.kt b/app/src/community/java/com/twilio/video/app/auth/CommunityAuthenticator.kt new file mode 100644 index 000000000..e852f2f1b --- /dev/null +++ b/app/src/community/java/com/twilio/video/app/auth/CommunityAuthenticator.kt @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 Twilio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.twilio.video.app.auth + +import android.content.SharedPreferences +import com.twilio.video.app.base.BaseActivity +import com.twilio.video.app.data.Preferences +import com.twilio.video.app.ui.login.CommunityLoginActivity + +class CommunityAuthenticator(private val preferences: SharedPreferences) : Authenticator { + + override fun getLoginActivity(): Class { + return CommunityLoginActivity::class.java + } + + override fun loggedIn(): Boolean { + return !preferences.getString(Preferences.DISPLAY_NAME, null).isNullOrEmpty() + } + + override fun logout() { + preferences.edit().remove(Preferences.DISPLAY_NAME).apply() + } +} diff --git a/app/src/community/java/com/twilio/video/app/data/CommunityDataModule.java b/app/src/community/java/com/twilio/video/app/data/CommunityDataModule.java index 2bf721cc9..549be8a7f 100644 --- a/app/src/community/java/com/twilio/video/app/data/CommunityDataModule.java +++ b/app/src/community/java/com/twilio/video/app/data/CommunityDataModule.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2019 Twilio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.twilio.video.app.data; import com.twilio.video.app.ApplicationScope; diff --git a/app/src/community/java/com/twilio/video/app/data/CommunityTokenService.java b/app/src/community/java/com/twilio/video/app/data/CommunityTokenService.java index 4fc721724..595d03087 100644 --- a/app/src/community/java/com/twilio/video/app/data/CommunityTokenService.java +++ b/app/src/community/java/com/twilio/video/app/data/CommunityTokenService.java @@ -1,9 +1,24 @@ +/* + * Copyright (C) 2019 Twilio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.twilio.video.app.data; import com.twilio.video.app.BuildConfig; import com.twilio.video.app.data.api.TokenService; import com.twilio.video.app.data.api.model.RoomProperties; - import io.reactivex.Single; public class CommunityTokenService implements TokenService { @@ -13,7 +28,6 @@ public class CommunityTokenService implements TokenService { */ @Override public Single getToken(final String identity, final RoomProperties roomProperties) { - return Single.fromCallable( - () -> BuildConfig.TWILIO_ACCESS_TOKEN); + return Single.fromCallable(() -> BuildConfig.TWILIO_ACCESS_TOKEN); } } diff --git a/app/src/community/java/com/twilio/video/app/ui/login/CommunityLoginActivity.java b/app/src/community/java/com/twilio/video/app/ui/login/CommunityLoginActivity.java index ae9456b4a..100a75604 100644 --- a/app/src/community/java/com/twilio/video/app/ui/login/CommunityLoginActivity.java +++ b/app/src/community/java/com/twilio/video/app/ui/login/CommunityLoginActivity.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2019 Twilio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.twilio.video.app.ui.login; import android.content.Intent; @@ -8,9 +24,7 @@ import android.view.View; import android.widget.Button; import android.widget.EditText; - import androidx.core.content.res.ResourcesCompat; - import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -53,7 +67,7 @@ public void onTextChanged(Editable editable) { @OnClick(R.id.login_button) public void onLoginButton(View view) { String name = nameEditText.getText().toString(); - if (name != null && name.length() > 0) { + if (name.length() > 0) { saveIdentity(name); startLobbyActivity(); } diff --git a/app/src/community/java/com/twilio/video/app/ui/login/CommunityLoginActivityModule.java b/app/src/community/java/com/twilio/video/app/ui/login/CommunityLoginActivityModule.java index 87fe3731d..884dbf4d7 100644 --- a/app/src/community/java/com/twilio/video/app/ui/login/CommunityLoginActivityModule.java +++ b/app/src/community/java/com/twilio/video/app/ui/login/CommunityLoginActivityModule.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2019 Twilio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.twilio.video.app.ui.login; import android.app.Activity; diff --git a/app/src/community/java/com/twilio/video/app/ui/login/CommunityLoginActivitySubcomponent.java b/app/src/community/java/com/twilio/video/app/ui/login/CommunityLoginActivitySubcomponent.java index 31654a0b3..dbdaf8fe6 100644 --- a/app/src/community/java/com/twilio/video/app/ui/login/CommunityLoginActivitySubcomponent.java +++ b/app/src/community/java/com/twilio/video/app/ui/login/CommunityLoginActivitySubcomponent.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2019 Twilio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.twilio.video.app.ui.login; import dagger.Subcomponent; diff --git a/app/src/internal/java/com/twilio/video/app/VideoApplicationComponent.java b/app/src/internal/java/com/twilio/video/app/VideoApplicationComponent.java index 5a87f23cc..426ad409c 100644 --- a/app/src/internal/java/com/twilio/video/app/VideoApplicationComponent.java +++ b/app/src/internal/java/com/twilio/video/app/VideoApplicationComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/ApplicationModule.java b/app/src/main/java/com/twilio/video/app/ApplicationModule.java index ad3f22305..9d5e8738c 100644 --- a/app/src/main/java/com/twilio/video/app/ApplicationModule.java +++ b/app/src/main/java/com/twilio/video/app/ApplicationModule.java @@ -1,7 +1,7 @@ package com.twilio.video.app; /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import android.app.Application; import dagger.Module; import dagger.Provides; @@ -32,4 +33,4 @@ public ApplicationModule(Application app) { Application provideApplication() { return app; } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/twilio/video/app/ApplicationScope.java b/app/src/main/java/com/twilio/video/app/ApplicationScope.java index 3130e80cb..ca9c79299 100644 --- a/app/src/main/java/com/twilio/video/app/ApplicationScope.java +++ b/app/src/main/java/com/twilio/video/app/ApplicationScope.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/TreeModule.java b/app/src/main/java/com/twilio/video/app/TreeModule.java index fea76821f..ac71fb4b8 100644 --- a/app/src/main/java/com/twilio/video/app/TreeModule.java +++ b/app/src/main/java/com/twilio/video/app/TreeModule.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/VideoApplication.java b/app/src/main/java/com/twilio/video/app/VideoApplication.java index e8a69518a..60d959231 100644 --- a/app/src/main/java/com/twilio/video/app/VideoApplication.java +++ b/app/src/main/java/com/twilio/video/app/VideoApplication.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,20 +19,16 @@ import android.app.Activity; import android.app.Application; import android.content.Context; - import androidx.multidex.MultiDex; - import dagger.android.DispatchingAndroidInjector; -import dagger.android.HasDispatchingActivityInjector; +import dagger.android.HasActivityInjector; import javax.inject.Inject; import timber.log.Timber; -public class VideoApplication extends Application implements HasDispatchingActivityInjector { +public class VideoApplication extends Application implements HasActivityInjector { @Inject DispatchingAndroidInjector dispatchingActivityInjector; @Inject Timber.Tree tree; - private VideoApplicationComponent applicationComponent; - @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); @@ -44,7 +40,7 @@ public void onCreate() { super.onCreate(); // Create application component and inject application - applicationComponent = + VideoApplicationComponent applicationComponent = DaggerVideoApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .build(); diff --git a/app/src/main/java/com/twilio/video/app/VideoApplicationGraph.java b/app/src/main/java/com/twilio/video/app/VideoApplicationGraph.java index c001d9f76..8897e8452 100644 --- a/app/src/main/java/com/twilio/video/app/VideoApplicationGraph.java +++ b/app/src/main/java/com/twilio/video/app/VideoApplicationGraph.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,6 @@ package com.twilio.video.app; -public interface VideoApplicationGraph { +interface VideoApplicationGraph { void inject(VideoApplication videoApplication); } diff --git a/app/src/main/java/com/twilio/video/app/adapter/IceServerAdapter.java b/app/src/main/java/com/twilio/video/app/adapter/IceServerAdapter.java index 3c89cf546..253a4ea4e 100644 --- a/app/src/main/java/com/twilio/video/app/adapter/IceServerAdapter.java +++ b/app/src/main/java/com/twilio/video/app/adapter/IceServerAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/adapter/StatsListAdapter.java b/app/src/main/java/com/twilio/video/app/adapter/StatsListAdapter.java deleted file mode 100644 index f8a163ac7..000000000 --- a/app/src/main/java/com/twilio/video/app/adapter/StatsListAdapter.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (C) 2017 Twilio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twilio.video.app.adapter; - -import android.content.Context; -import android.os.Handler; -import android.os.Looper; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TableRow; -import android.widget.TextView; - -import androidx.recyclerview.widget.RecyclerView; - -import butterknife.BindView; -import butterknife.ButterKnife; -import com.google.common.collect.ImmutableList; -import com.twilio.video.LocalAudioTrackStats; -import com.twilio.video.LocalVideoTrackStats; -import com.twilio.video.RemoteAudioTrack; -import com.twilio.video.RemoteAudioTrackPublication; -import com.twilio.video.RemoteAudioTrackStats; -import com.twilio.video.RemoteParticipant; -import com.twilio.video.RemoteVideoTrack; -import com.twilio.video.RemoteVideoTrackPublication; -import com.twilio.video.RemoteVideoTrackStats; -import com.twilio.video.StatsReport; -import com.twilio.video.app.R; -import com.twilio.video.app.model.StatsListItem; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class StatsListAdapter extends RecyclerView.Adapter { - - public static class ViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.stats_track_name) - TextView trackNameText; - - @BindView(R.id.stats_track_sid_value) - TextView trackSidValueText; - - @BindView(R.id.stats_codec_value) - TextView codecValueText; - - @BindView(R.id.stats_packets_value) - TextView packetsValueText; - - @BindView(R.id.stats_bytes_title) - TextView bytesTitleText; - - @BindView(R.id.stats_bytes_value) - TextView bytesValueText; - - @BindView(R.id.stats_rtt_value) - TextView rttValueText; - - @BindView(R.id.stats_jitter_value) - TextView jitterValueText; - - @BindView(R.id.stats_audio_level_value) - TextView audioLevelValueText; - - @BindView(R.id.stats_dimensions_value) - TextView dimensionsValueText; - - @BindView(R.id.stats_framerate_value) - TextView framerateValueText; - - @BindView(R.id.stats_rtt_row) - TableRow rttTableRow; - - @BindView(R.id.stats_jitter_row) - TableRow jitterTableRow; - - @BindView(R.id.stats_audio_level_row) - TableRow audioLevelTableRow; - - @BindView(R.id.stats_dimensions_row) - TableRow dimensionsTableRow; - - @BindView(R.id.stats_framerate_row) - TableRow framerateTableRow; - - public ViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - } - } - - private ArrayList statsListItems = new ArrayList<>(); - private Context context; - private Handler handler; - - public StatsListAdapter(Context context) { - this.context = context; - handler = new Handler(Looper.getMainLooper()); - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View v = - LayoutInflater.from(parent.getContext()) - .inflate(R.layout.stats_layout, parent, false); - return new ViewHolder(v); - } - - @Override - public void onBindViewHolder(ViewHolder holder, int position) { - StatsListItem item = statsListItems.get(position); - holder.trackNameText.setText(item.trackName); - holder.trackSidValueText.setText(item.trackSid); - holder.codecValueText.setText(item.codec); - holder.packetsValueText.setText(String.valueOf(item.packetsLost)); - holder.bytesValueText.setText(String.valueOf(item.bytes)); - if (item.isLocalTrack) { - holder.bytesTitleText.setText(context.getString(R.string.stats_bytes_sent)); - holder.rttValueText.setText(String.valueOf(item.rtt)); - holder.rttTableRow.setVisibility(View.VISIBLE); - } else { - holder.rttTableRow.setVisibility(View.GONE); - holder.bytesTitleText.setText(context.getString(R.string.stats_bytes_received)); - } - if (item.isAudioTrack) { - holder.jitterValueText.setText(String.valueOf(item.jitter)); - holder.audioLevelValueText.setText(String.valueOf(item.audioLevel)); - holder.dimensionsTableRow.setVisibility(View.GONE); - holder.framerateTableRow.setVisibility(View.GONE); - holder.jitterTableRow.setVisibility(View.VISIBLE); - holder.audioLevelTableRow.setVisibility(View.VISIBLE); - } else { - holder.dimensionsValueText.setText(item.dimensions); - holder.framerateValueText.setText(String.valueOf(item.framerate)); - holder.dimensionsTableRow.setVisibility(View.VISIBLE); - holder.framerateTableRow.setVisibility(View.VISIBLE); - holder.jitterTableRow.setVisibility(View.GONE); - holder.audioLevelTableRow.setVisibility(View.GONE); - } - } - - @Override - public int getItemCount() { - return statsListItems.size(); - } - - public void updateStatsData( - List statsReports, - List remoteParticipants, - Map localVideoTrackNames) { - /* - * Generate new items on a separate list to ensure statsListItems changes are only - * performed on the UI thread to meet the threading requirement of RecyclerView.Adapter. - */ - ImmutableList.Builder statsListItemsBuilder = new ImmutableList.Builder<>(); - - // Generate stats items list from reports - boolean localTracksAdded = false; - for (StatsReport report : statsReports) { - if (!localTracksAdded) { - // go trough local tracks - for (LocalAudioTrackStats localAudioTrackStats : report.getLocalAudioTrackStats()) { - StatsListItem item = - new StatsListItem.Builder() - .baseTrackInfo(localAudioTrackStats) - .bytes(localAudioTrackStats.bytesSent) - .rtt(localAudioTrackStats.roundTripTime) - .jitter(localAudioTrackStats.jitter) - .audioLevel(localAudioTrackStats.audioLevel) - .trackName(context.getString(R.string.local_audio_track)) - .isAudioTrack(true) - .isLocalTrack(true) - .build(); - statsListItemsBuilder.add(item); - } - for (LocalVideoTrackStats localVideoTrackStats : report.getLocalVideoTrackStats()) { - String localVideoTrackName = - localVideoTrackNames.get(localVideoTrackStats.trackSid); - if (localVideoTrackName == null) { - localVideoTrackName = context.getString(R.string.local_video_track); - } - StatsListItem item = - new StatsListItem.Builder() - .baseTrackInfo(localVideoTrackStats) - .bytes(localVideoTrackStats.bytesSent) - .rtt(localVideoTrackStats.roundTripTime) - .dimensions(localVideoTrackStats.dimensions.toString()) - .framerate(localVideoTrackStats.frameRate) - .trackName(localVideoTrackName) - .isAudioTrack(false) - .isLocalTrack(true) - .build(); - statsListItemsBuilder.add(item); - } - localTracksAdded = true; - } - int trackCount = 0; - for (RemoteAudioTrackStats remoteAudioTrackStats : report.getRemoteAudioTrackStats()) { - String trackName = - getParticipantName(remoteAudioTrackStats.trackSid, true, remoteParticipants) - + " " - + context.getString(R.string.audio_track) - + " " - + trackCount; - StatsListItem item = - new StatsListItem.Builder() - .baseTrackInfo(remoteAudioTrackStats) - .bytes(remoteAudioTrackStats.bytesReceived) - .jitter(remoteAudioTrackStats.jitter) - .audioLevel(remoteAudioTrackStats.audioLevel) - .trackName(trackName) - .isAudioTrack(true) - .isLocalTrack(false) - .build(); - statsListItemsBuilder.add(item); - trackCount++; - } - trackCount = 0; - for (RemoteVideoTrackStats remoteVideoTrackStats : report.getRemoteVideoTrackStats()) { - String trackName = - getParticipantName( - remoteVideoTrackStats.trackSid, false, remoteParticipants) - + " " - + context.getString(R.string.video_track) - + " " - + trackCount; - StatsListItem item = - new StatsListItem.Builder() - .baseTrackInfo(remoteVideoTrackStats) - .bytes(remoteVideoTrackStats.bytesReceived) - .dimensions(remoteVideoTrackStats.dimensions.toString()) - .framerate(remoteVideoTrackStats.frameRate) - .trackName(trackName) - .isAudioTrack(false) - .isLocalTrack(false) - .build(); - statsListItemsBuilder.add(item); - trackCount++; - } - } - - final ImmutableList immutableStatsListItems = statsListItemsBuilder.build(); - - handler.post( - () -> { - statsListItems.clear(); - statsListItems.addAll(immutableStatsListItems); - notifyDataSetChanged(); - }); - } - - private String getParticipantName( - String trackSid, boolean isAudioTrack, List remoteParticipants) { - for (RemoteParticipant remoteParticipant : remoteParticipants) { - if (isAudioTrack) { - RemoteAudioTrack remoteAudioTrack = getAudioTrack(remoteParticipant, trackSid); - if (remoteAudioTrack != null) { - return remoteParticipant.getIdentity(); - } - } else { - RemoteVideoTrack remoteVideoTrack = - getRemoteVideoTrack(remoteParticipant, trackSid); - if (remoteVideoTrack != null) { - return remoteParticipant.getIdentity(); - } - } - } - return ""; - } - - private RemoteAudioTrack getAudioTrack(RemoteParticipant remoteParticipant, String trackSid) { - for (RemoteAudioTrackPublication remoteAudioTrackPublication : - remoteParticipant.getRemoteAudioTracks()) { - if (remoteAudioTrackPublication.getTrackSid().equals(trackSid)) { - return remoteAudioTrackPublication.getRemoteAudioTrack(); - } - } - - return null; - } - - private RemoteVideoTrack getRemoteVideoTrack( - RemoteParticipant remoteParticipant, String trackSid) { - for (RemoteVideoTrackPublication remoteVideoTrackPublication : - remoteParticipant.getRemoteVideoTracks()) { - if (remoteVideoTrackPublication.getTrackSid().equals(trackSid)) { - return remoteVideoTrackPublication.getRemoteVideoTrack(); - } - } - - return null; - } -} diff --git a/app/src/main/java/com/twilio/video/app/adapter/StatsListAdapter.kt b/app/src/main/java/com/twilio/video/app/adapter/StatsListAdapter.kt new file mode 100644 index 000000000..e324445d1 --- /dev/null +++ b/app/src/main/java/com/twilio/video/app/adapter/StatsListAdapter.kt @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2019 Twilio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.twilio.video.app.adapter + +import android.content.Context +import android.os.Handler +import android.os.Looper +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TableRow +import android.widget.TextView + +import androidx.recyclerview.widget.RecyclerView + +import butterknife.BindView +import butterknife.ButterKnife +import com.twilio.video.RemoteAudioTrack +import com.twilio.video.RemoteParticipant +import com.twilio.video.RemoteVideoTrack +import com.twilio.video.StatsReport +import com.twilio.video.app.R +import com.twilio.video.app.model.StatsListItem +import java.util.ArrayList + +class StatsListAdapter(private val context: Context) : RecyclerView.Adapter() { + + private val statsListItems = ArrayList() + private val handler: Handler = Handler(Looper.getMainLooper()) + + class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + @BindView(R.id.stats_track_name) + internal var trackNameText: TextView? = null + + @BindView(R.id.stats_track_sid_value) + internal var trackSidValueText: TextView? = null + + @BindView(R.id.stats_codec_value) + internal var codecValueText: TextView? = null + + @BindView(R.id.stats_packets_value) + internal var packetsValueText: TextView? = null + + @BindView(R.id.stats_bytes_title) + internal var bytesTitleText: TextView? = null + + @BindView(R.id.stats_bytes_value) + internal var bytesValueText: TextView? = null + + @BindView(R.id.stats_rtt_value) + internal var rttValueText: TextView? = null + + @BindView(R.id.stats_jitter_value) + internal var jitterValueText: TextView? = null + + @BindView(R.id.stats_audio_level_value) + internal var audioLevelValueText: TextView? = null + + @BindView(R.id.stats_dimensions_value) + internal var dimensionsValueText: TextView? = null + + @BindView(R.id.stats_framerate_value) + internal var framerateValueText: TextView? = null + + @BindView(R.id.stats_rtt_row) + internal var rttTableRow: TableRow? = null + + @BindView(R.id.stats_jitter_row) + internal var jitterTableRow: TableRow? = null + + @BindView(R.id.stats_audio_level_row) + internal var audioLevelTableRow: TableRow? = null + + @BindView(R.id.stats_dimensions_row) + internal var dimensionsTableRow: TableRow? = null + + @BindView(R.id.stats_framerate_row) + internal var framerateTableRow: TableRow? = null + + init { + ButterKnife.bind(this, itemView) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val v = LayoutInflater.from(parent.context) + .inflate(R.layout.stats_layout, parent, false) + return ViewHolder(v) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val item = statsListItems[position] + holder.trackNameText!!.text = item.trackName + holder.trackSidValueText!!.text = item.trackSid + holder.codecValueText!!.text = item.codec + holder.packetsValueText!!.text = item.packetsLost.toString() + holder.bytesValueText!!.text = item.bytes.toString() + if (item.isLocalTrack) { + holder.bytesTitleText!!.text = context.getString(R.string.stats_bytes_sent) + holder.rttValueText!!.text = item.rtt.toString() + holder.rttTableRow!!.visibility = View.VISIBLE + } else { + holder.rttTableRow!!.visibility = View.GONE + holder.bytesTitleText!!.text = context.getString(R.string.stats_bytes_received) + } + if (item.isAudioTrack) { + holder.jitterValueText!!.text = item.jitter.toString() + holder.audioLevelValueText!!.text = item.audioLevel.toString() + holder.dimensionsTableRow!!.visibility = View.GONE + holder.framerateTableRow!!.visibility = View.GONE + holder.jitterTableRow!!.visibility = View.VISIBLE + holder.audioLevelTableRow!!.visibility = View.VISIBLE + } else { + holder.dimensionsValueText!!.text = item.dimensions + holder.framerateValueText!!.text = item.framerate.toString() + holder.dimensionsTableRow!!.visibility = View.VISIBLE + holder.framerateTableRow!!.visibility = View.VISIBLE + holder.jitterTableRow!!.visibility = View.GONE + holder.audioLevelTableRow!!.visibility = View.GONE + } + } + + override fun getItemCount(): Int { + return statsListItems.size + } + + fun updateStatsData( + statsReports: List, + remoteParticipants: List, + localVideoTrackNames: Map + ) { + /* + * Generate new items on a separate list to ensure statsListItems changes are only + * performed on the UI thread to meet the threading requirement of RecyclerView.Adapter. + */ + val statsItemList = mutableListOf() + + // Generate stats items list from reports + var localTracksAdded = false + for (report in statsReports) { + if (!localTracksAdded) { + // go trough local tracks + for (localAudioTrackStats in report.localAudioTrackStats) { + val item = StatsListItem.Builder() + .baseTrackInfo(localAudioTrackStats) + .bytes(localAudioTrackStats.bytesSent) + .rtt(localAudioTrackStats.roundTripTime) + .jitter(localAudioTrackStats.jitter) + .audioLevel(localAudioTrackStats.audioLevel) + .trackName(context.getString(R.string.local_audio_track)) + .isAudioTrack(true) + .isLocalTrack(true) + .build() + statsItemList.add(item) + } + for (localVideoTrackStats in report.localVideoTrackStats) { + var localVideoTrackName = localVideoTrackNames[localVideoTrackStats.trackSid] + if (localVideoTrackName == null) { + localVideoTrackName = context.getString(R.string.local_video_track) + } + val item = StatsListItem.Builder() + .baseTrackInfo(localVideoTrackStats) + .bytes(localVideoTrackStats.bytesSent) + .rtt(localVideoTrackStats.roundTripTime) + .dimensions(localVideoTrackStats.dimensions.toString()) + .framerate(localVideoTrackStats.frameRate) + .trackName(localVideoTrackName) + .isAudioTrack(false) + .isLocalTrack(true) + .build() + statsItemList.add(item) + } + localTracksAdded = true + } + var trackCount = 0 + for (remoteAudioTrackStats in report.remoteAudioTrackStats) { + val trackName = (getParticipantName(remoteAudioTrackStats.trackSid, true, remoteParticipants) + + " " + + context.getString(R.string.audio_track) + + " " + + trackCount) + val item = StatsListItem.Builder() + .baseTrackInfo(remoteAudioTrackStats) + .bytes(remoteAudioTrackStats.bytesReceived) + .jitter(remoteAudioTrackStats.jitter) + .audioLevel(remoteAudioTrackStats.audioLevel) + .trackName(trackName) + .isAudioTrack(true) + .isLocalTrack(false) + .build() + statsItemList.add(item) + trackCount++ + } + trackCount = 0 + for (remoteVideoTrackStats in report.remoteVideoTrackStats) { + val trackName = (getParticipantName( + remoteVideoTrackStats.trackSid, false, remoteParticipants) + + " " + + context.getString(R.string.video_track) + + " " + + trackCount) + val item = StatsListItem.Builder() + .baseTrackInfo(remoteVideoTrackStats) + .bytes(remoteVideoTrackStats.bytesReceived) + .dimensions(remoteVideoTrackStats.dimensions.toString()) + .framerate(remoteVideoTrackStats.frameRate) + .trackName(trackName) + .isAudioTrack(false) + .isLocalTrack(false) + .build() + statsItemList.add(item) + trackCount++ + } + } + + handler.post { + statsListItems.clear() + statsListItems.addAll(statsListItems.toList()) + notifyDataSetChanged() + } + } + + private fun getParticipantName( + trackSid: String, + isAudioTrack: Boolean, + remoteParticipants: List + ): String { + for (remoteParticipant in remoteParticipants) { + if (isAudioTrack) { + val remoteAudioTrack = getAudioTrack(remoteParticipant, trackSid) + if (remoteAudioTrack != null) { + return remoteParticipant.identity + } + } else { + val remoteVideoTrack = getRemoteVideoTrack(remoteParticipant, trackSid) + if (remoteVideoTrack != null) { + return remoteParticipant.identity + } + } + } + return "" + } + + private fun getAudioTrack(remoteParticipant: RemoteParticipant, trackSid: String): RemoteAudioTrack? { + for (remoteAudioTrackPublication in remoteParticipant.remoteAudioTracks) { + if (remoteAudioTrackPublication.trackSid == trackSid) { + return remoteAudioTrackPublication.remoteAudioTrack + } + } + + return null + } + + private fun getRemoteVideoTrack( + remoteParticipant: RemoteParticipant, + trackSid: String + ): RemoteVideoTrack? { + for (remoteVideoTrackPublication in remoteParticipant.remoteVideoTracks) { + if (remoteVideoTrackPublication.trackSid == trackSid) { + return remoteVideoTrackPublication.remoteVideoTrack + } + } + + return null + } +} diff --git a/app/src/main/java/com/twilio/video/app/auth/AuthModule.java b/app/src/main/java/com/twilio/video/app/auth/AuthModule.java index 19aff34e0..13d356427 100644 --- a/app/src/main/java/com/twilio/video/app/auth/AuthModule.java +++ b/app/src/main/java/com/twilio/video/app/auth/AuthModule.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/auth/Authenticator.java b/app/src/main/java/com/twilio/video/app/auth/Authenticator.java index 34269b0e3..c7938bb76 100644 --- a/app/src/main/java/com/twilio/video/app/auth/Authenticator.java +++ b/app/src/main/java/com/twilio/video/app/auth/Authenticator.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/auth/FirebaseAuthenticator.java b/app/src/main/java/com/twilio/video/app/auth/FirebaseAuthenticator.java index 53c3eb9fc..b4cafca70 100644 --- a/app/src/main/java/com/twilio/video/app/auth/FirebaseAuthenticator.java +++ b/app/src/main/java/com/twilio/video/app/auth/FirebaseAuthenticator.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/base/BaseActivity.java b/app/src/main/java/com/twilio/video/app/base/BaseActivity.java index 5e70ae163..5e9153969 100644 --- a/app/src/main/java/com/twilio/video/app/base/BaseActivity.java +++ b/app/src/main/java/com/twilio/video/app/base/BaseActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,7 @@ package com.twilio.video.app.base; import android.os.Bundle; - import androidx.appcompat.app.AppCompatActivity; - import dagger.android.AndroidInjection; public abstract class BaseActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/twilio/video/app/data/DataModule.java b/app/src/main/java/com/twilio/video/app/data/DataModule.java index 22f6290f1..b523d6553 100644 --- a/app/src/main/java/com/twilio/video/app/data/DataModule.java +++ b/app/src/main/java/com/twilio/video/app/data/DataModule.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/data/NumberPreference.java b/app/src/main/java/com/twilio/video/app/data/NumberPreference.java index 8cf3aa04f..dcef21256 100644 --- a/app/src/main/java/com/twilio/video/app/data/NumberPreference.java +++ b/app/src/main/java/com/twilio/video/app/data/NumberPreference.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,7 @@ import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; - import androidx.preference.DialogPreference; - import com.twilio.video.app.R; import java.util.Locale; @@ -85,6 +83,8 @@ protected Object onGetDefaultValue(TypedArray a, int index) { return a.getInt(index, 0); } + // TODO Use non deprecated method and use SharedPreferences to get persisted value + // https://issues.corp.twilio.com/browse/AHOYAPPS-111 @Override protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) { setNumber(restorePersistedValue ? getPersistedInt(number) : (int) defaultValue); diff --git a/app/src/main/java/com/twilio/video/app/data/NumberPreferenceDialogFragmentCompat.java b/app/src/main/java/com/twilio/video/app/data/NumberPreferenceDialogFragmentCompat.java index 7760270b9..e484f722e 100644 --- a/app/src/main/java/com/twilio/video/app/data/NumberPreferenceDialogFragmentCompat.java +++ b/app/src/main/java/com/twilio/video/app/data/NumberPreferenceDialogFragmentCompat.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,10 +19,8 @@ import android.os.Bundle; import android.view.View; import android.widget.EditText; - import androidx.preference.DialogPreference; import androidx.preference.PreferenceDialogFragmentCompat; - import com.twilio.video.app.R; import java.util.Locale; @@ -56,7 +54,7 @@ protected void onBindDialogView(View view) { super.onBindDialogView(view); // init input field - numberInput = (EditText) view.findViewById(R.id.edit); + numberInput = view.findViewById(R.id.edit); // obtain reference to preference DialogPreference preference = getPreference(); diff --git a/app/src/main/java/com/twilio/video/app/data/Preferences.java b/app/src/main/java/com/twilio/video/app/data/Preferences.java index 56e5605f8..6f25cfd2b 100644 --- a/app/src/main/java/com/twilio/video/app/data/Preferences.java +++ b/app/src/main/java/com/twilio/video/app/data/Preferences.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/data/RangeBarPreference.java b/app/src/main/java/com/twilio/video/app/data/RangeBarPreference.java index 3b73fc470..c3df2e199 100644 --- a/app/src/main/java/com/twilio/video/app/data/RangeBarPreference.java +++ b/app/src/main/java/com/twilio/video/app/data/RangeBarPreference.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,11 +25,9 @@ import android.preference.PreferenceManager; import android.util.AttributeSet; import android.widget.LinearLayout; - import androidx.annotation.Nullable; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; - import com.appyvet.rangebar.IRangeBarFormatter; import com.appyvet.rangebar.RangeBar; import com.twilio.video.app.R; @@ -37,25 +35,12 @@ /** * RangeBarPreference allows to save any range in default shared preferences by saving range start * and range end values. - * - *

Customizable options: - * - * @attr name entries - collection of string to use as display value - * @attr name heightResId - range bar height - * @attr name startTick - range bar start - * @attr name endTick - range bar end - * @attr name pinRadius - size of pin - * @attr name startKey - string used as key to save value in shared preferences. - * @attr name endKey - string used as key to save value in shared preferences. */ public class RangeBarPreference extends Preference { /** Default shared preferences instance. */ private SharedPreferences sharedPreferences; - /** Customizable range bar. */ - private RangeBar rangeBar; - /** * RangeBar pin visible text formatter. If entries array is provided utilizes string values from * the provided array, otherwise falls back to integers. @@ -112,10 +97,11 @@ public void onBindViewHolder(PreferenceViewHolder holder) { // obtain resources for range bar height calculations. Resources resources = holder.itemView.getContext().getResources(); - rangeBar = (RangeBar) holder.findViewById(R.id.range_bar); + /** Customizable range bar. */ + RangeBar rangeBar1 = (RangeBar) holder.findViewById(R.id.range_bar); // apply custom height - rangeBar.setLayoutParams( + rangeBar1.setLayoutParams( new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, resources.getDimensionPixelSize(heightResId))); @@ -126,8 +112,8 @@ public void onBindViewHolder(PreferenceViewHolder holder) { endTick = entries.length - 1; } - rangeBar.setTickStart(startTick); - rangeBar.setTickEnd(endTick); + rangeBar1.setTickStart(startTick); + rangeBar1.setTickEnd(endTick); // obtain selected range int start = sharedPreferences.getInt(startKey, -1); @@ -141,29 +127,27 @@ public void onBindViewHolder(PreferenceViewHolder holder) { end = endTick; } - rangeBar.setRangePinsByValue(start, end); + rangeBar1.setRangePinsByValue(start, end); // apply pin size if (pinRadius != -1.0f) { - rangeBar.setPinRadius(pinRadius); + rangeBar1.setPinRadius(pinRadius); } // apply range bar value text formatter visible on choosing pins - if (rangeBar != null) { - - if (formatter != null) { - rangeBar.setFormatter(formatter); - } - // save all changes prefs while moving pins - rangeBar.setOnRangeBarChangeListener( - (rangeBar, leftPinIndex, rightPinIndex, leftPinValue, rightPinValue) -> - sharedPreferences - .edit() - .putInt(startKey, leftPinIndex) - .putInt(endKey, rightPinIndex) - .apply()); + if (formatter != null) { + rangeBar1.setFormatter(formatter); } + + // save all changes prefs while moving pins + rangeBar1.setOnRangeBarChangeListener( + (rangeBar, leftPinIndex, rightPinIndex, leftPinValue, rightPinValue) -> + sharedPreferences + .edit() + .putInt(startKey, leftPinIndex) + .putInt(endKey, rightPinIndex) + .apply()); } private void init(Context context, @Nullable AttributeSet attrs) { diff --git a/app/src/main/java/com/twilio/video/app/data/api/FirebaseAuthInterceptor.java b/app/src/main/java/com/twilio/video/app/data/api/FirebaseAuthInterceptor.java index afd968e56..db375d2e0 100644 --- a/app/src/main/java/com/twilio/video/app/data/api/FirebaseAuthInterceptor.java +++ b/app/src/main/java/com/twilio/video/app/data/api/FirebaseAuthInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import okhttp3.Response; import timber.log.Timber; -public class FirebaseAuthInterceptor implements Interceptor { +class FirebaseAuthInterceptor implements Interceptor { private static final int FIREBASE_TOKEN_TIMEOUT_MS = 10000; private static final String HEADER_AUTHORIZATION = "Authorization"; private static final String FIREBASE_TOKEN_TASK_FAILED = "Failed to get Firebase Token"; diff --git a/app/src/main/java/com/twilio/video/app/data/api/TokenService.kt b/app/src/main/java/com/twilio/video/app/data/api/TokenService.kt index d923542ff..f2d3cd4c7 100644 --- a/app/src/main/java/com/twilio/video/app/data/api/TokenService.kt +++ b/app/src/main/java/com/twilio/video/app/data/api/TokenService.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/data/api/TwilioApiEnvironment.kt b/app/src/main/java/com/twilio/video/app/data/api/TwilioApiEnvironment.kt index 61f7b3b3a..ade25241f 100644 --- a/app/src/main/java/com/twilio/video/app/data/api/TwilioApiEnvironment.kt +++ b/app/src/main/java/com/twilio/video/app/data/api/TwilioApiEnvironment.kt @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2019 Twilio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.twilio.video.app.data.api const val TWILIO_API_DEV_ENV = "dev" diff --git a/app/src/main/java/com/twilio/video/app/data/api/VideoAppService.java b/app/src/main/java/com/twilio/video/app/data/api/VideoAppService.java index 48e5c7b34..7069dd3a2 100644 --- a/app/src/main/java/com/twilio/video/app/data/api/VideoAppService.java +++ b/app/src/main/java/com/twilio/video/app/data/api/VideoAppService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/data/api/VideoAppServiceDelegate.kt b/app/src/main/java/com/twilio/video/app/data/api/VideoAppServiceDelegate.kt index d93e8dcdf..71e6da8f2 100644 --- a/app/src/main/java/com/twilio/video/app/data/api/VideoAppServiceDelegate.kt +++ b/app/src/main/java/com/twilio/video/app/data/api/VideoAppServiceDelegate.kt @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2019 Twilio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.twilio.video.app.data.api import android.content.SharedPreferences @@ -8,10 +24,11 @@ import io.reactivex.Single import timber.log.Timber class VideoAppServiceDelegate( - private val sharedPreferences: SharedPreferences, - private val videoAppServiceDev: VideoAppService, - private val videoAppServiceStage: VideoAppService, - private val videoAppServiceProd: VideoAppService) : TokenService { + private val sharedPreferences: SharedPreferences, + private val videoAppServiceDev: VideoAppService, + private val videoAppServiceStage: VideoAppService, + private val videoAppServiceProd: VideoAppService +) : TokenService { override fun getToken(identity: String, roomProperties: RoomProperties): Single { val env = sharedPreferences.getString( @@ -30,7 +47,7 @@ class VideoAppServiceDelegate( private fun resolveAppEnvironment(appFlavor: String): String { // Video App Service only accepts internal and production for app environment - return if(TWILIO_API_DEV_ENV == appFlavor) { + return if (TWILIO_API_DEV_ENV == appFlavor) { "internal" } else "production" } diff --git a/app/src/main/java/com/twilio/video/app/data/api/VideoAppServiceModule.java b/app/src/main/java/com/twilio/video/app/data/api/VideoAppServiceModule.java index e4a35c973..dae292a29 100644 --- a/app/src/main/java/com/twilio/video/app/data/api/VideoAppServiceModule.java +++ b/app/src/main/java/com/twilio/video/app/data/api/VideoAppServiceModule.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/data/api/model/RoomProperties.java b/app/src/main/java/com/twilio/video/app/data/api/model/RoomProperties.java index 65d09188c..6daf4ec36 100644 --- a/app/src/main/java/com/twilio/video/app/data/api/model/RoomProperties.java +++ b/app/src/main/java/com/twilio/video/app/data/api/model/RoomProperties.java @@ -15,16 +15,15 @@ */ package com.twilio.video.app.data.api.model; - import androidx.annotation.NonNull; +import org.jetbrains.annotations.NotNull; public class RoomProperties { - @NonNull - private String name; + @NonNull private String name; @NonNull private Topology topology; private boolean recordParticipantsOnConnect; - RoomProperties( + private RoomProperties( @NonNull final String name, @NonNull final Topology topology, boolean recordParticipantsOnConnect) { @@ -33,10 +32,12 @@ public class RoomProperties { this.recordParticipantsOnConnect = recordParticipantsOnConnect; } + @NotNull public Topology getTopology() { return topology; } + @NotNull public String getName() { return name; } diff --git a/app/src/main/java/com/twilio/video/app/data/api/model/Topology.java b/app/src/main/java/com/twilio/video/app/data/api/model/Topology.java index 8f1bb2226..0aa153851 100644 --- a/app/src/main/java/com/twilio/video/app/data/api/model/Topology.java +++ b/app/src/main/java/com/twilio/video/app/data/api/model/Topology.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/dialog/Dialog.java b/app/src/main/java/com/twilio/video/app/dialog/Dialog.java deleted file mode 100644 index e4b139d91..000000000 --- a/app/src/main/java/com/twilio/video/app/dialog/Dialog.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2017 Twilio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twilio.video.app.dialog; - -import android.content.Context; -import android.content.DialogInterface; -import android.widget.EditText; - -import androidx.appcompat.app.AlertDialog; - -import com.twilio.video.app.R; -import com.twilio.video.app.model.TwilioIceServer; -import java.util.List; - -public class Dialog { - public static IceServersDialogFragment createIceServersDialog( - List iceServers, IceServersDialogFragment.Listener listener) { - IceServersDialogFragment dialog = new IceServersDialogFragment(); - dialog.setIceServers(iceServers); - dialog.setListener(listener); - return dialog; - } - - public static AlertDialog createConnectDialog( - EditText roomEditText, - DialogInterface.OnClickListener connectClickListener, - DialogInterface.OnClickListener cancelClickListener, - Context context) { - AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context); - - alertDialogBuilder.setIcon(R.drawable.ic_call_black_24dp); - alertDialogBuilder.setTitle("Connect to Room"); - alertDialogBuilder.setPositiveButton("Connect", connectClickListener); - alertDialogBuilder.setNegativeButton("Cancel", cancelClickListener); - alertDialogBuilder.setCancelable(false); - - setRoomtFieldInDialog(roomEditText, alertDialogBuilder, context); - - return alertDialogBuilder.create(); - } - - private static void setRoomtFieldInDialog( - EditText roomEditText, AlertDialog.Builder alertDialogBuilder, Context context) { - roomEditText.setHint("Room Name"); - - int horizontalPadding = - context.getResources().getDimensionPixelOffset(R.dimen.activity_horizontal_margin); - int verticalPadding = - context.getResources().getDimensionPixelOffset(R.dimen.activity_vertical_margin); - roomEditText.setPadding( - horizontalPadding, verticalPadding, horizontalPadding, verticalPadding); - alertDialogBuilder.setView(roomEditText); - } -} diff --git a/app/src/main/java/com/twilio/video/app/dialog/IceServersDialogFragment.java b/app/src/main/java/com/twilio/video/app/dialog/IceServersDialogFragment.java index 2f8cb1ed2..843073f97 100644 --- a/app/src/main/java/com/twilio/video/app/dialog/IceServersDialogFragment.java +++ b/app/src/main/java/com/twilio/video/app/dialog/IceServersDialogFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,9 +26,7 @@ import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Spinner; - import androidx.appcompat.app.AppCompatDialogFragment; - import butterknife.BindView; import butterknife.ButterKnife; import butterknife.Unbinder; @@ -38,7 +36,9 @@ import com.twilio.video.app.util.IceOptionsHelper; import java.util.ArrayList; import java.util.List; +import org.jetbrains.annotations.NotNull; +// TODO Cleanup unused references https://issues.corp.twilio.com/browse/AHOYAPPS-112 public class IceServersDialogFragment extends AppCompatDialogFragment { public interface Listener { @@ -68,20 +68,21 @@ public void setListener(Listener listener) { this.listener = listener; } + @NotNull @Override public android.app.Dialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - LayoutInflater inflater = getActivity().getLayoutInflater(); + AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()); + LayoutInflater inflater = requireActivity().getLayoutInflater(); @SuppressLint("InflateParams") View iceOptionsView = inflater.inflate(R.layout.ice_options_layout, null); unbinder = ButterKnife.bind(this, iceOptionsView); - IceServerAdapter iceServerAdapter = new IceServerAdapter(getActivity(), iceServers); + IceServerAdapter iceServerAdapter = new IceServerAdapter(requireActivity(), iceServers); iceServersListView.setAdapter(iceServerAdapter); ArrayAdapter iceTransPolicyArrayAdapter = ArrayAdapter.createFromResource( - getActivity(), + requireActivity(), R.array.ice_trans_policy_array, android.R.layout.simple_spinner_item); iceTransPolicyArrayAdapter.setDropDownViewResource( diff --git a/app/src/main/java/com/twilio/video/app/model/StatsListItem.java b/app/src/main/java/com/twilio/video/app/model/StatsListItem.java index af18c59c7..caaa9c786 100644 --- a/app/src/main/java/com/twilio/video/app/model/StatsListItem.java +++ b/app/src/main/java/com/twilio/video/app/model/StatsListItem.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,16 +68,6 @@ public Builder trackName(String trackName) { return this; } - public Builder codec(String codec) { - this.codec = codec; - return this; - } - - public Builder packetsLost(int packetsLost) { - this.packetsLost = packetsLost; - return this; - } - public Builder bytes(long bytes) { this.bytes = bytes; return this; diff --git a/app/src/main/java/com/twilio/video/app/model/TwilioIceResponse.java b/app/src/main/java/com/twilio/video/app/model/TwilioIceResponse.java deleted file mode 100644 index d90c6fec1..000000000 --- a/app/src/main/java/com/twilio/video/app/model/TwilioIceResponse.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2017 Twilio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twilio.video.app.model; - -import com.google.gson.annotations.SerializedName; -import java.util.List; - -public class TwilioIceResponse { - - public static final String ICE_TRANSPORT_POLICY = "ice_transport_type"; - public static final String ICE_SELECTED_SERVERS = "ice_selected_servers"; - public static final String ICE_SERVERS = "ice_servers"; - - private String username; - - private String password; - - @SerializedName("account_sid") - private String accountSid; - - @SerializedName("ice_servers") - private List iceServers; - - @SerializedName("date_created") - private String dateCreated; - - @SerializedName("date_updated") - private String dateUpdated; - - public TwilioIceResponse() {} - - public String getUsername() { - return username; - } - - public String getPassword() { - return password; - } - - public String getAccountSid() { - return accountSid; - } - - public List getIceServers() { - return iceServers; - } - - public String getDateCreated() { - return dateCreated; - } - - public String getDateUpdated() { - return dateUpdated; - } -} diff --git a/app/src/main/java/com/twilio/video/app/model/TwilioIceServer.java b/app/src/main/java/com/twilio/video/app/model/TwilioIceServer.java index 9feb9e5dd..060900b07 100644 --- a/app/src/main/java/com/twilio/video/app/model/TwilioIceServer.java +++ b/app/src/main/java/com/twilio/video/app/model/TwilioIceServer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,29 +16,20 @@ package com.twilio.video.app.model; +import org.jetbrains.annotations.NotNull; + public class TwilioIceServer { private String url; - private String username; - private String credential; public TwilioIceServer() { url = ""; - username = ""; - credential = ""; } public String getUrl() { return url; } - public String getUsername() { - return username; - } - - public String getCredential() { - return credential; - } - + @NotNull public String toString() { return url; } diff --git a/app/src/main/java/com/twilio/video/app/ui/login/ExistingAccountLoginFragment.java b/app/src/main/java/com/twilio/video/app/ui/login/ExistingAccountLoginFragment.java index d529d8eae..9d57cb7f9 100644 --- a/app/src/main/java/com/twilio/video/app/ui/login/ExistingAccountLoginFragment.java +++ b/app/src/main/java/com/twilio/video/app/ui/login/ExistingAccountLoginFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,10 +27,8 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; - import androidx.core.content.res.ResourcesCompat; import androidx.fragment.app.Fragment; - import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -88,9 +86,7 @@ public void onTextChanged(Editable editable) { public void onLoginButton(View view) { String email = emailEditText.getText().toString(); String password = passwordEditText.getText().toString(); - if (email != null - && email.length() > 0 - && password != null + if (email.length() > 0 && password.length() > 0 && Patterns.EMAIL_ADDRESS.matcher(email).matches() && (mListener != null)) { diff --git a/app/src/main/java/com/twilio/video/app/ui/login/LoginActivity.java b/app/src/main/java/com/twilio/video/app/ui/login/LoginActivity.java index 4933b9698..ad0bd9660 100644 --- a/app/src/main/java/com/twilio/video/app/ui/login/LoginActivity.java +++ b/app/src/main/java/com/twilio/video/app/ui/login/LoginActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,9 +21,7 @@ import android.content.SharedPreferences; import android.os.Bundle; import android.view.ViewGroup; - import androidx.appcompat.app.AlertDialog; - import butterknife.BindView; import butterknife.ButterKnife; import com.google.android.gms.auth.api.Auth; @@ -119,12 +117,13 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); if (result != null && result.isSuccess()) { GoogleSignInAccount account = result.getSignInAccount(); - AuthHelper.signInWithGoogle(account, this, errorListener); - } else { + if (account != null) { + AuthHelper.signInWithGoogle(account, this, errorListener); + } // TODO: failed to sign in with google } + super.onActivityResult(requestCode, resultCode, data); } - super.onActivityResult(requestCode, resultCode, data); } // LoginLandingFragment @@ -216,12 +215,11 @@ private void processError(@AuthHelper.Error int errorCode) { } private void showUnauthorizedEmailDialog() { - AlertDialog dialog = - new AlertDialog.Builder(this, R.style.AppTheme_Dialog) - .setTitle(getString(R.string.unauthorized_title)) - .setMessage(getString(R.string.unauthorized_desc)) - .setPositiveButton("OK", null) - .show(); + new AlertDialog.Builder(this, R.style.AppTheme_Dialog) + .setTitle(getString(R.string.unauthorized_title)) + .setMessage(getString(R.string.unauthorized_desc)) + .setPositiveButton("OK", null) + .show(); } private void dismissAuthenticatingDialog() { @@ -230,7 +228,7 @@ private void dismissAuthenticatingDialog() { } } - private void showAuthenticatingDialog() { + void showAuthenticatingDialog() { progressDialog = new ProgressDialog(this, R.style.Authenticating); progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progressDialog.setMessage("Authenticating"); @@ -239,7 +237,7 @@ private void showAuthenticatingDialog() { progressDialog.show(); } - public void onSignInSuccess() { + private void onSignInSuccess() { dismissAuthenticatingDialog(); startLobbyActivity(); } diff --git a/app/src/main/java/com/twilio/video/app/ui/login/LoginActivityModule.java b/app/src/main/java/com/twilio/video/app/ui/login/LoginActivityModule.java index e156c0351..322674271 100644 --- a/app/src/main/java/com/twilio/video/app/ui/login/LoginActivityModule.java +++ b/app/src/main/java/com/twilio/video/app/ui/login/LoginActivityModule.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/ui/login/LoginActivitySubcomponent.java b/app/src/main/java/com/twilio/video/app/ui/login/LoginActivitySubcomponent.java index 9d467bf12..f0c477835 100644 --- a/app/src/main/java/com/twilio/video/app/ui/login/LoginActivitySubcomponent.java +++ b/app/src/main/java/com/twilio/video/app/ui/login/LoginActivitySubcomponent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/ui/login/LoginLandingFragment.java b/app/src/main/java/com/twilio/video/app/ui/login/LoginLandingFragment.java index 7f4b288e7..85d3d0785 100644 --- a/app/src/main/java/com/twilio/video/app/ui/login/LoginLandingFragment.java +++ b/app/src/main/java/com/twilio/video/app/ui/login/LoginLandingFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,9 +22,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; - import androidx.fragment.app.Fragment; - import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; diff --git a/app/src/main/java/com/twilio/video/app/ui/room/ClearableEditText.java b/app/src/main/java/com/twilio/video/app/ui/room/ClearableEditText.java index 1959833e1..dbc867281 100644 --- a/app/src/main/java/com/twilio/video/app/ui/room/ClearableEditText.java +++ b/app/src/main/java/com/twilio/video/app/ui/room/ClearableEditText.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,25 +24,21 @@ import android.text.TextWatcher; import android.util.AttributeSet; import android.view.MotionEvent; - import androidx.appcompat.widget.AppCompatEditText; import androidx.core.graphics.drawable.DrawableCompat; import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; - import com.twilio.video.app.R; +// TODO Replace custom view with TextInputLayout Material Component as part of +// https://issues.corp.twilio.com/browse/AHOYAPPS-109 /** * ClearableEditText is an extension for standard EditText with an extra option to setup clear icon * with as right compound drawable, which handles clear icon touch event as erase for the contents * of user input. - * - * @attr name clearIcon - clear action icon to display to the right of EditText input. */ public class ClearableEditText extends AppCompatEditText { - /** Clear icon resource id. */ - private int clearIconResId; - /** Clear icon drawable. */ + /** Clear action icon to display to the right of EditText input. */ private Drawable clearDrawable; public ClearableEditText(Context context) { @@ -68,7 +64,9 @@ private void init(Context context, AttributeSet attrs) { .obtainStyledAttributes(attrs, R.styleable.ClearableEditText, 0, 0); // obtain clear icon resource id - clearIconResId = stylables.getResourceId(R.styleable.ClearableEditText_clearIcon, -1); + /** Clear icon resource id. */ + int clearIconResId = + stylables.getResourceId(R.styleable.ClearableEditText_clearIcon, -1); if (clearIconResId != -1) { clearDrawable = VectorDrawableCompat.create(getResources(), clearIconResId, null); } @@ -76,7 +74,10 @@ private void init(Context context, AttributeSet attrs) { // setup initial clear icon state setCompoundDrawablesWithIntrinsicBounds(null, null, clearDrawable, null); - showClearIcon(getText().toString().length() > 0); + Editable text = getText(); + if (text != null) { + showClearIcon(text.toString().length() > 0); + } // update clear icon state after every text change addTextChangedListener( @@ -106,6 +107,10 @@ public void afterTextChanged(Editable editable) { } } + if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { + view.performClick(); + } + return false; }); } @@ -115,7 +120,7 @@ public void afterTextChanged(Editable editable) { * * @param show pass true to display icon, otherwise false to hide. */ - public void showClearIcon(boolean show) { + private void showClearIcon(boolean show) { // TODO: should probably use setVisibility method, but seems to not working. if (clearDrawable != null) { clearDrawable.setAlpha(show ? 255 : 0); @@ -127,7 +132,7 @@ public void showClearIcon(boolean show) { * * @return true if active, otherwise - false. */ - public boolean isClearVisible() { + private boolean isClearVisible() { return clearDrawable != null && DrawableCompat.getAlpha(clearDrawable) == 255; } } diff --git a/app/src/main/java/com/twilio/video/app/ui/room/ParticipantController.java b/app/src/main/java/com/twilio/video/app/ui/room/ParticipantController.java index 24bf12209..ebe65a601 100644 --- a/app/src/main/java/com/twilio/video/app/ui/room/ParticipantController.java +++ b/app/src/main/java/com/twilio/video/app/ui/room/ParticipantController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,14 +18,14 @@ import android.view.View; import android.view.ViewGroup; +import androidx.annotation.Nullable; import com.twilio.video.VideoTrack; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import javax.annotation.Nullable; /** ParticipantController is main controlling party for rendering participants. */ -public class ParticipantController { +class ParticipantController { /** * Data container about primary participant - sid, identity, video track, audio state and @@ -45,18 +45,17 @@ public class ParticipantController { /** Each participant thumb click listener. */ private ItemClickListener listener; - public ParticipantController( - ViewGroup thumbsViewContainer, ParticipantPrimaryView primaryVideoView) { + ParticipantController(ViewGroup thumbsViewContainer, ParticipantPrimaryView primaryVideoView) { this.thumbsViewContainer = thumbsViewContainer; this.primaryView = primaryVideoView; } - public void addThumb(String sid, String identity) { + private void addThumb(String sid, String identity) { addThumb(sid, identity, null, true, false, false); } - public void addThumb(Item item) { + void addThumb(Item item) { addThumb( item.sid, item.identity, @@ -66,7 +65,7 @@ public void addThumb(Item item) { item.showNetworkQualityLevel); } - public void addThumb(String sid, String identity, VideoTrack videoTrack) { + private void addThumb(String sid, String identity, VideoTrack videoTrack) { addThumb(sid, identity, videoTrack, true, false, false); } @@ -78,7 +77,7 @@ public void addThumb(String sid, String identity, VideoTrack videoTrack) { * @param videoTrack participant video to display or NULL for empty thumbs. * @param muted participant audio state. */ - public void addThumb( + void addThumb( String sid, String identity, VideoTrack videoTrack, @@ -97,7 +96,7 @@ public void addThumb( * * @param mirror enable/disable video track mirroring. */ - public void updatePrimaryThumb(boolean mirror) { + void updatePrimaryThumb(boolean mirror) { Item target = getPrimaryItem(); if (target != null) { ParticipantView view = getPrimaryView(); @@ -114,7 +113,7 @@ public void updatePrimaryThumb(boolean mirror) { * @param oldVideo video track to replace. * @param newVideo new video track to insert. */ - public void updateThumb(String sid, VideoTrack oldVideo, VideoTrack newVideo) { + void updateThumb(String sid, VideoTrack oldVideo, VideoTrack newVideo) { Item target = findItem(sid, oldVideo); if (target != null) { ParticipantView view = getThumb(sid, oldVideo); @@ -139,7 +138,7 @@ public void updateThumb(String sid, VideoTrack oldVideo, VideoTrack newVideo) { * @param videoTrack target video track. * @param state new thumb state. */ - public void updateThumb(String sid, VideoTrack videoTrack, @ParticipantView.State int state) { + void updateThumb(String sid, VideoTrack videoTrack, @ParticipantView.State int state) { Item target = findItem(sid, videoTrack); if (target != null) { ParticipantThumbView view = (ParticipantThumbView) getThumb(sid, videoTrack); @@ -164,7 +163,7 @@ public void updateThumb(String sid, VideoTrack videoTrack, @ParticipantView.Stat * @param videoTrack target video track. * @param mirror enable/disable mirror. */ - public void updateThumb(String sid, VideoTrack videoTrack, boolean mirror) { + void updateThumb(String sid, VideoTrack videoTrack, boolean mirror) { Item target = findItem(sid, videoTrack); if (target != null) { ParticipantThumbView view = (ParticipantThumbView) getThumb(sid, videoTrack); @@ -180,7 +179,7 @@ public void updateThumb(String sid, VideoTrack videoTrack, boolean mirror) { * @param sid unique participant identifier. * @param muted new audio state. */ - public void updateThumbs(String sid, boolean muted) { + void updateThumbs(String sid, boolean muted) { for (Map.Entry entry : thumbs.entrySet()) { if (entry.getKey().sid.equals(sid)) { entry.getKey().muted = muted; @@ -197,8 +196,7 @@ public void updateThumbs(String sid, boolean muted) { * @param oldVideo video track to replace. * @param newVideo new video track to insert. */ - public void addOrUpdateThumb( - String sid, String identity, VideoTrack oldVideo, VideoTrack newVideo) { + void addOrUpdateThumb(String sid, String identity, VideoTrack oldVideo, VideoTrack newVideo) { if (hasThumb(sid, oldVideo)) { updateThumb(sid, oldVideo, newVideo); @@ -207,7 +205,7 @@ public void addOrUpdateThumb( } } - public void removeThumb(Item item) { + void removeThumb(Item item) { removeThumb(item.sid, item.videoTrack); } @@ -217,7 +215,7 @@ public void removeThumb(Item item) { * @param sid unique participant identifier. * @param videoTrack target video track. */ - public void removeThumb(String sid, VideoTrack videoTrack) { + void removeThumb(String sid, VideoTrack videoTrack) { Item target = findItem(sid, videoTrack); if (target != null) { ParticipantView view = getThumb(sid, videoTrack); @@ -234,7 +232,7 @@ public void removeThumb(String sid, VideoTrack videoTrack) { * * @param sid unique participant identifier. */ - public void removeThumbs(String sid) { + void removeThumbs(String sid) { ArrayList deleteKeys = new ArrayList<>(); for (Map.Entry entry : thumbs.entrySet()) { if (entry.getKey().sid.equals(sid)) { @@ -259,7 +257,7 @@ public void removeThumbs(String sid) { * @param identity participant name to display. * @param videoTrack target video track. */ - public void removeOrEmptyThumb(String sid, String identity, VideoTrack videoTrack) { + void removeOrEmptyThumb(String sid, String identity, VideoTrack videoTrack) { int thumbsCount = getThumbs(sid).size(); if (thumbsCount > 1 || (thumbsCount == 1 && primaryItem.sid.equals(sid))) { removeThumb(sid, videoTrack); @@ -277,7 +275,7 @@ public void removeOrEmptyThumb(String sid, String identity, VideoTrack videoTrac * @param videoTrack target video track. * @return participant thumb instance. */ - public ParticipantView getThumb(String sid, VideoTrack videoTrack) { + ParticipantView getThumb(String sid, VideoTrack videoTrack) { for (Map.Entry entry : thumbs.entrySet()) { if (entry.getKey() != null && entry.getKey().sid.equals(sid) @@ -289,7 +287,7 @@ public ParticipantView getThumb(String sid, VideoTrack videoTrack) { } /** Remove all thumbs for all participants. */ - public void removeAllThumbs() { + void removeAllThumbs() { for (Map.Entry entry : thumbs.entrySet()) { thumbsViewContainer.removeView(entry.getValue()); if (entry.getKey() != null) { @@ -299,7 +297,7 @@ public void removeAllThumbs() { thumbs.clear(); } - public void renderAsPrimary(Item item) { + void renderAsPrimary(Item item) { renderAsPrimary(item.sid, item.identity, item.videoTrack, item.muted, item.mirror); } @@ -312,7 +310,7 @@ public void renderAsPrimary(Item item) { * @param muted participant audio state. * @param mirror enable/disable mirroring for video track. */ - public void renderAsPrimary( + void renderAsPrimary( String sid, String identity, VideoTrack videoTrack, boolean muted, boolean mirror) { Item old = primaryItem; @@ -339,7 +337,7 @@ public void renderAsPrimary( } /** Remove primary participant. */ - public void removePrimary() { + void removePrimary() { removeRender(primaryItem.videoTrack, primaryView); // TODO: temp state primaryView.setState(ParticipantView.State.NO_VIDEO); @@ -351,7 +349,7 @@ public void removePrimary() { * * @return participant item data. */ - public Item getPrimaryItem() { + Item getPrimaryItem() { return primaryItem; } @@ -360,15 +358,15 @@ public Item getPrimaryItem() { * * @return primary participant view instance. */ - public ParticipantPrimaryView getPrimaryView() { + ParticipantPrimaryView getPrimaryView() { return primaryView; } - public void setListener(ItemClickListener listener) { + void setListener(ItemClickListener listener) { this.listener = listener; } - public void setDominantSpeaker(@Nullable ParticipantView participantView) { + void setDominantSpeaker(@Nullable ParticipantView participantView) { clearDominantSpeaker(); if (participantView != null) { participantView.dominantSpeakerImg.setVisibility(View.VISIBLE); @@ -436,7 +434,7 @@ private void removeRender(VideoTrack videoTrack, ParticipantView view) { } /** RemoteParticipant information data holder. */ - public static class Item { + static class Item { /** RemoteParticipant unique identifier. */ String sid; @@ -455,8 +453,7 @@ public static class Item { boolean showNetworkQualityLevel; - public Item( - String sid, String identity, VideoTrack videoTrack, boolean muted, boolean mirror) { + Item(String sid, String identity, VideoTrack videoTrack, boolean muted, boolean mirror) { this.sid = sid; this.identity = identity; @@ -465,7 +462,7 @@ public Item( this.mirror = mirror; } - public Item( + Item( String sid, String identity, VideoTrack videoTrack, diff --git a/app/src/main/java/com/twilio/video/app/ui/room/ParticipantPrimaryView.java b/app/src/main/java/com/twilio/video/app/ui/room/ParticipantPrimaryView.java index a18b499bd..44a09f208 100644 --- a/app/src/main/java/com/twilio/video/app/ui/room/ParticipantPrimaryView.java +++ b/app/src/main/java/com/twilio/video/app/ui/room/ParticipantPrimaryView.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,31 +29,33 @@ public class ParticipantPrimaryView extends ParticipantView { public ParticipantPrimaryView(Context context) { super(context); - init(context, null); + init(context); } public ParticipantPrimaryView(Context context, AttributeSet attrs) { super(context, attrs); - init(context, attrs); + init(context); } public ParticipantPrimaryView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - init(context, attrs); + init(context); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public ParticipantPrimaryView( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); - init(context, attrs); + init(context); } public void showIdentityBadge(boolean show) { - identityBadge.setVisibility(show ? VISIBLE : GONE); + if (identityBadge != null) { + identityBadge.setVisibility(show ? VISIBLE : GONE); + } } - private void init(Context context, AttributeSet attrs) { + private void init(Context context) { View view = LayoutInflater.from(context).inflate(R.layout.participant_view_primary, this); ButterKnife.bind(this, view); diff --git a/app/src/main/java/com/twilio/video/app/ui/room/ParticipantThumbView.java b/app/src/main/java/com/twilio/video/app/ui/room/ParticipantThumbView.java index 0a6de2da5..b6db5215b 100644 --- a/app/src/main/java/com/twilio/video/app/ui/room/ParticipantThumbView.java +++ b/app/src/main/java/com/twilio/video/app/ui/room/ParticipantThumbView.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,9 +22,7 @@ import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; - import androidx.core.content.ContextCompat; - import butterknife.ButterKnife; import com.twilio.video.app.R; @@ -32,27 +30,27 @@ public class ParticipantThumbView extends ParticipantView { public ParticipantThumbView(Context context) { super(context); - init(context, null); + init(context); } public ParticipantThumbView(Context context, AttributeSet attrs) { super(context, attrs); - init(context, attrs); + init(context); } public ParticipantThumbView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - init(context, attrs); + init(context); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public ParticipantThumbView( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); - init(context, attrs); + init(context); } - private void init(Context context, AttributeSet attrs) { + private void init(Context context) { View view = LayoutInflater.from(context).inflate(R.layout.participant_view, this); ButterKnife.bind(this, view); diff --git a/app/src/main/java/com/twilio/video/app/ui/room/ParticipantView.java b/app/src/main/java/com/twilio/video/app/ui/room/ParticipantView.java index cfd2efeae..f9025c548 100644 --- a/app/src/main/java/com/twilio/video/app/ui/room/ParticipantView.java +++ b/app/src/main/java/com/twilio/video/app/ui/room/ParticipantView.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,14 +25,12 @@ import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; - import androidx.annotation.AttrRes; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StyleRes; import androidx.constraintlayout.widget.ConstraintLayout; - import butterknife.BindView; import com.twilio.video.I420Frame; import com.twilio.video.VideoRenderer; @@ -44,11 +42,10 @@ abstract class ParticipantView extends FrameLayout implements VideoRenderer { - protected String identity = ""; - protected int state = State.NO_VIDEO; - protected boolean mirror = false; - protected int scaleType = VideoScaleType.ASPECT_BALANCED.ordinal(); - protected boolean overlaySurface = true; + String identity = ""; + int state = State.NO_VIDEO; + boolean mirror = false; + int scaleType = VideoScaleType.ASPECT_BALANCED.ordinal(); @BindView(R.id.participant_video_layout) ConstraintLayout videoLayout; @@ -98,7 +95,7 @@ public ParticipantView( } @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public ParticipantView( + ParticipantView( @NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @@ -145,7 +142,7 @@ public void setMirror(boolean mirror) { videoView.setMirror(this.mirror); } - public void setScaleType(int scaleType) { + void setScaleType(int scaleType) { this.scaleType = scaleType; videoView.setVideoScaleType(VideoScaleType.values()[this.scaleType]); } @@ -159,7 +156,7 @@ public void renderFrame(@NonNull I420Frame frame) { videoView.renderFrame(frame); } - protected void initParams(Context context, AttributeSet attrs) { + void initParams(Context context, AttributeSet attrs) { if (attrs != null) { TypedArray stylables = context.getTheme() @@ -183,9 +180,6 @@ protected void initParams(Context context, AttributeSet attrs) { R.styleable.ParticipantView_type, VideoScaleType.ASPECT_BALANCED.ordinal()); - // obtain overlay - overlaySurface = stylables.getBoolean(R.styleable.ParticipantView_overlaySurface, true); - stylables.recycle(); } } diff --git a/app/src/main/java/com/twilio/video/app/ui/room/RoomActivity.java b/app/src/main/java/com/twilio/video/app/ui/room/RoomActivity.java index 2406ffe8b..dd04e2cca 100644 --- a/app/src/main/java/com/twilio/video/app/ui/room/RoomActivity.java +++ b/app/src/main/java/com/twilio/video/app/ui/room/RoomActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ import android.media.projection.MediaProjectionManager; import android.os.Build; import android.os.Bundle; +import android.text.Editable; import android.text.TextUtils; import android.view.Menu; import android.view.MenuInflater; @@ -47,7 +48,6 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; @@ -56,12 +56,10 @@ import androidx.core.content.PermissionChecker; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; - import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; import butterknife.OnTextChanged; - import com.google.android.material.snackbar.Snackbar; import com.twilio.androidenv.Env; import com.twilio.video.AspectRatio; @@ -128,6 +126,7 @@ import java.util.Locale; import java.util.Map; import javax.inject.Inject; +import org.jetbrains.annotations.NotNull; import timber.log.Timber; public class RoomActivity extends BaseActivity { @@ -235,7 +234,7 @@ public class RoomActivity extends BaseActivity { new ScreenCapturer.Listener() { @Override public void onScreenCaptureError(@NonNull String errorDescription) { - Timber.e("Screen capturer error: " + errorDescription); + Timber.e("Screen capturer error: %s", errorDescription); stopScreenCapture(); Snackbar.make( primaryVideoView, @@ -321,7 +320,7 @@ protected void onDestroy() { @Override public void onRequestPermissionsResult( - int requestCode, String[] permissions, int[] grantResults) { + int requestCode, @NotNull String[] permissions, @NotNull int[] grantResults) { if (requestCode == PERMISSIONS_REQUEST_CODE) { boolean recordAudioPermissionGranted = grantResults[0] == PackageManager.PERMISSION_GRANTED; @@ -460,52 +459,56 @@ void connectButtonClick() { } connect.setEnabled(false); // obtain room name - final String roomName = roomEditText.getText().toString(); - // obtain latest environment preferences - - RoomProperties roomProperties = - new RoomProperties.Builder() - .setName(roomName) - .setTopology( - Topology.fromString( - sharedPreferences.getString( - Preferences.TOPOLOGY, - Preferences.TOPOLOGY_DEFAULT))) - .setRecordOnParticipantsConnect( - sharedPreferences.getBoolean( - Preferences.RECORD_PARTICIPANTS_ON_CONNECT, - Preferences.RECORD_PARTICIPANTS_ON_CONNECT_DEFAULT)) - .createRoomProperties(); - Single connection = - updateEnv() - .andThen(tokenService.getToken(displayName, roomProperties)) - .flatMap(token -> connect(token, roomName)); - - connection - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - new SingleObserver() { - @Override - public void onSubscribe(Disposable disposable) { - InputUtils.hideKeyboard(RoomActivity.this); - rxDisposables.add(disposable); - } - - @Override - public void onSuccess(Room room) { - RoomActivity.this.room = room; - updateUi(room); - } - - @Override - public void onError(Throwable e) { - final String message = "Failed to retrieve access token"; - Timber.e("%s -> reason: %s", message, e.getMessage()); - Snackbar.make(primaryVideoView, message, Snackbar.LENGTH_LONG) - .show(); - connect.setEnabled(true); - } - }); + + Editable text = roomEditText.getText(); + if (text != null) { + final String roomName = text.toString(); + // obtain latest environment preferences + RoomProperties roomProperties = + new RoomProperties.Builder() + .setName(roomName) + .setTopology( + Topology.fromString( + sharedPreferences.getString( + Preferences.TOPOLOGY, + Preferences.TOPOLOGY_DEFAULT))) + .setRecordOnParticipantsConnect( + sharedPreferences.getBoolean( + Preferences.RECORD_PARTICIPANTS_ON_CONNECT, + Preferences.RECORD_PARTICIPANTS_ON_CONNECT_DEFAULT)) + .createRoomProperties(); + + Single connection = + updateEnv() + .andThen(tokenService.getToken(displayName, roomProperties)) + .flatMap(token -> connect(token, roomName)); + + connection + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + new SingleObserver() { + @Override + public void onSubscribe(Disposable disposable) { + InputUtils.hideKeyboard(RoomActivity.this); + rxDisposables.add(disposable); + } + + @Override + public void onSuccess(Room room) { + RoomActivity.this.room = room; + updateUi(room); + } + + @Override + public void onError(Throwable e) { + final String message = "Failed to retrieve access token"; + Timber.e("%s -> reason: %s", message, e.getMessage()); + Snackbar.make(primaryVideoView, message, Snackbar.LENGTH_LONG) + .show(); + connect.setEnabled(true); + } + }); + } } @OnClick(R.id.disconnect) @@ -518,10 +521,10 @@ void disconnectButtonClick() { @OnClick(R.id.local_audio_image_button) void toggleLocalAudio() { - int icon = 0; + int icon; if (localAudioTrack == null) { localAudioTrack = LocalAudioTrack.create(this, true); - if (localParticipant != null) { + if (localParticipant != null && localAudioTrack != null) { localParticipant.publishTrack(localAudioTrack); } icon = R.drawable.ic_mic_white_24px; @@ -552,16 +555,17 @@ void toggleLocalVideo() { cameraVideoTrack = LocalVideoTrack.create( this, true, cameraCapturer.getVideoCapturer(), videoConstraints); - if (localParticipant != null) { + if (localParticipant != null && cameraVideoTrack != null) { localParticipant.publishTrack(cameraVideoTrack); - } - - // enable video settings - switchCameraMenuItem.setVisible(cameraVideoTrack.isEnabled()); - pauseVideoMenuItem.setTitle( - cameraVideoTrack.isEnabled() ? R.string.pause_video : R.string.resume_video); - pauseVideoMenuItem.setVisible(true); + // enable video settings + switchCameraMenuItem.setVisible(cameraVideoTrack.isEnabled()); + pauseVideoMenuItem.setTitle( + cameraVideoTrack.isEnabled() + ? R.string.pause_video + : R.string.resume_video); + pauseVideoMenuItem.setVisible(true); + } } else { // remove local camera track cameraVideoTrack.removeRenderer(primaryVideoView); @@ -625,7 +629,7 @@ private String getDisplayName() { * Append serial number for internal or development flavor so the same account can be used * across different devices. */ - return BuildConfigUtils.isInternalFlavor() || BuildConfigUtils.isDevelopmentFlavor() + return BuildConfigUtils.isInternalFlavor() || BuildConfigUtils.isCommunityFlavor() ? displayName + String.format(Locale.getDefault(), " %d", System.currentTimeMillis()) : displayName; @@ -638,12 +642,13 @@ private void obtainVideoConstraints() { // setup aspect ratio String aspectRatio = sharedPreferences.getString(Preferences.ASPECT_RATIO, "0"); - int aspectRatioIndex = Integer.parseInt(aspectRatio); - builder.aspectRatio(aspectRatios[aspectRatioIndex]); - - Timber.d( - "Aspect ratio : %s", - getResources().getStringArray(R.array.aspect_ratio_array)[aspectRatioIndex]); + if (aspectRatio != null) { + int aspectRatioIndex = Integer.parseInt(aspectRatio); + builder.aspectRatio(aspectRatios[aspectRatioIndex]); + Timber.d( + "Aspect ratio : %s", + getResources().getStringArray(R.array.aspect_ratio_array)[aspectRatioIndex]); + } // setup video dimensions int minVideoDim = sharedPreferences.getInt(Preferences.MIN_VIDEO_DIMENSIONS, 0); @@ -675,40 +680,49 @@ private void obtainVideoConstraints() { videoConstraints = builder.build(); } - private VideoCodec getVideoCodecPreference(String key, String defaultValue) { - final String videoCodecName = sharedPreferences.getString(key, defaultValue); - - switch (videoCodecName) { - case Vp8Codec.NAME: - boolean simulcast = - sharedPreferences.getBoolean( - Preferences.VP8_SIMULCAST, Preferences.VP8_SIMULCAST_DEFAULT); - return new Vp8Codec(simulcast); - case H264Codec.NAME: - return new H264Codec(); - case Vp9Codec.NAME: - return new Vp9Codec(); - default: - return new Vp8Codec(); + private VideoCodec getVideoCodecPreference(String key) { + final String videoCodecName = + sharedPreferences.getString(key, Preferences.VIDEO_CODEC_DEFAULT); + + if (videoCodecName != null) { + switch (videoCodecName) { + case Vp8Codec.NAME: + boolean simulcast = + sharedPreferences.getBoolean( + Preferences.VP8_SIMULCAST, Preferences.VP8_SIMULCAST_DEFAULT); + return new Vp8Codec(simulcast); + case H264Codec.NAME: + return new H264Codec(); + case Vp9Codec.NAME: + return new Vp9Codec(); + default: + return new Vp8Codec(); + } + } else { + return new Vp8Codec(); } } - private AudioCodec getAudioCodecPreference(String key, String defaultValue) { - final String audioCodecName = sharedPreferences.getString(key, defaultValue); - - switch (audioCodecName) { - case IsacCodec.NAME: - return new IsacCodec(); - case OpusCodec.NAME: - return new OpusCodec(); - case PcmaCodec.NAME: - return new PcmaCodec(); - case PcmuCodec.NAME: - return new PcmuCodec(); - case G722Codec.NAME: - return new G722Codec(); - default: - return new OpusCodec(); + private AudioCodec getAudioCodecPreference() { + final String audioCodecName = + sharedPreferences.getString( + Preferences.AUDIO_CODEC, Preferences.AUDIO_CODEC_DEFAULT); + + if (audioCodecName != null) { + switch (audioCodecName) { + case IsacCodec.NAME: + return new IsacCodec(); + case PcmaCodec.NAME: + return new PcmaCodec(); + case PcmuCodec.NAME: + return new PcmuCodec(); + case G722Codec.NAME: + return new G722Codec(); + default: + return new OpusCodec(); + } + } else { + return new OpusCodec(); } } @@ -890,7 +904,7 @@ private void setAudioFocus(boolean setFocus) { if (setFocus) { savedIsSpeakerPhoneOn = audioManager.isSpeakerphoneOn(); savedIsMicrophoneMute = audioManager.isMicrophoneMute(); - setMicrophoneMute(false); + setMicrophoneMute(); savedAudioMode = audioManager.getMode(); // Request audio focus before making any device switch. requestAudioFocus(); @@ -932,12 +946,12 @@ private void requestAudioFocus() { } /** Sets the microphone mute state. */ - private void setMicrophoneMute(boolean on) { + private void setMicrophoneMute() { boolean wasMuted = audioManager.isMicrophoneMute(); - if (wasMuted == on) { + if (!wasMuted) { return; } - audioManager.setMicrophoneMute(on); + audioManager.setMicrophoneMute(false); } private void setVolumeControl(boolean setVolumeControl) { @@ -1064,12 +1078,9 @@ private Single connect(final String token, final String roomName) { Preferences.ENABLE_DOMINANT_SPEAKER_DEFAULT); VideoCodec preferedVideoCodec = - getVideoCodecPreference( - Preferences.VIDEO_CODEC, Preferences.VIDEO_CODEC_DEFAULT); + getVideoCodecPreference(Preferences.VIDEO_CODEC); - AudioCodec preferredAudioCodec = - getAudioCodecPreference( - Preferences.AUDIO_CODEC, Preferences.AUDIO_CODEC_DEFAULT); + AudioCodec preferredAudioCodec = getAudioCodecPreference(); ConnectOptions.Builder connectOptionsBuilder = new ConnectOptions.Builder(token) @@ -1425,12 +1436,12 @@ public void onConnectFailure( @Override public void onReconnecting( @NonNull Room room, @NonNull TwilioException twilioException) { - Timber.i("onReconnecting: " + room.getName()); + Timber.i("onReconnecting: %s", room.getName()); } @Override public void onReconnected(@NonNull Room room) { - Timber.i("onReconnected: " + room.getName()); + Timber.i("onReconnected: %s", room.getName()); } @Override @@ -1496,7 +1507,7 @@ public void onDominantSpeakerChanged( if (participantView != null) { participantController.setDominantSpeaker(participantView); } else { - String remoteIdentity = remoteParticipant.getIdentity(); + remoteParticipant.getIdentity(); ParticipantPrimaryView primaryParticipantView = participantController.getPrimaryView(); if (primaryParticipantView.identity.equals( @@ -1512,12 +1523,12 @@ public void onDominantSpeakerChanged( @Override public void onRecordingStarted(@NonNull Room room) { - Timber.i("onRecordingStarted: " + room.getName()); + Timber.i("onRecordingStarted: %s", room.getName()); } @Override public void onRecordingStopped(@NonNull Room room) { - Timber.i("onRecordingStopped: " + room.getName()); + Timber.i("onRecordingStopped: %s", room.getName()); } }; } @@ -1590,8 +1601,7 @@ public void onAudioTrackPublished( @NonNull RemoteParticipant remoteParticipant, @NonNull RemoteAudioTrackPublication remoteAudioTrackPublication) { Timber.i( - "onAudioTrackPublished: remoteParticipant: %s, audio: %s, enabled: %b, " - + "subscribed: %b", + "onAudioTrackPublished: remoteParticipant: %s, audio: %s, enabled: %b, subscribed: %b", remoteParticipant.getIdentity(), remoteAudioTrackPublication.getTrackSid(), remoteAudioTrackPublication.isTrackEnabled(), @@ -1605,8 +1615,7 @@ public void onAudioTrackUnpublished( @NonNull RemoteParticipant remoteParticipant, @NonNull RemoteAudioTrackPublication remoteAudioTrackPublication) { Timber.i( - "onAudioTrackUnpublished: remoteParticipant: %s, audio: %s, enabled: %b, " - + "subscribed: %b", + "onAudioTrackUnpublished: remoteParticipant: %s, audio: %s, enabled: %b, subscribed: %b", remoteParticipant.getIdentity(), remoteAudioTrackPublication.getTrackSid(), remoteAudioTrackPublication.isTrackEnabled(), @@ -1619,8 +1628,7 @@ public void onVideoTrackPublished( @NonNull RemoteParticipant remoteParticipant, @NonNull RemoteVideoTrackPublication remoteVideoTrackPublication) { Timber.i( - "onVideoTrackPublished: remoteParticipant: %s, video: %s, enabled: %b, " - + "subscribed: %b", + "onVideoTrackPublished: remoteParticipant: %s, video: %s, enabled: %b, subscribed: %b", remoteParticipant.getIdentity(), remoteVideoTrackPublication.getTrackSid(), remoteVideoTrackPublication.isTrackEnabled(), @@ -1633,8 +1641,7 @@ public void onVideoTrackUnpublished( @NonNull RemoteParticipant remoteParticipant, @NonNull RemoteVideoTrackPublication remoteVideoTrackPublication) { Timber.i( - "onVideoTrackUnpublished: remoteParticipant: %s, video: %s, enabled: %b, " - + "subscribed: %b", + "onVideoTrackUnpublished: remoteParticipant: %s, video: %s, enabled: %b, subscribed: %b", remoteParticipant.getIdentity(), remoteVideoTrackPublication.getTrackSid(), remoteVideoTrackPublication.isTrackEnabled(), @@ -1648,8 +1655,7 @@ public void onAudioTrackSubscribed( @NonNull RemoteAudioTrackPublication remoteAudioTrackPublication, @NonNull RemoteAudioTrack remoteAudioTrack) { Timber.i( - "onAudioTrackSubscribed: remoteParticipant: %s, audio: %s, enabled: %b, " - + "subscribed: %b", + "onAudioTrackSubscribed: remoteParticipant: %s, audio: %s, enabled: %b, subscribed: %b", remoteParticipant.getIdentity(), remoteAudioTrackPublication.getTrackSid(), remoteAudioTrackPublication.isTrackEnabled(), @@ -1675,8 +1681,7 @@ public void onAudioTrackSubscriptionFailed( @NonNull RemoteAudioTrackPublication remoteAudioTrackPublication, @NonNull TwilioException twilioException) { Timber.w( - "onAudioTrackSubscriptionFailed: remoteParticipant: %s, video: %s, " - + "exception: %s", + "onAudioTrackSubscriptionFailed: remoteParticipant: %s, video: %s, exception: %s", remoteParticipant.getIdentity(), remoteAudioTrackPublication.getTrackSid(), twilioException.getMessage()); @@ -1691,25 +1696,22 @@ public void onAudioTrackUnsubscribed( @NonNull RemoteAudioTrackPublication remoteAudioTrackPublication, @NonNull RemoteAudioTrack remoteAudioTrack) { Timber.i( - "onAudioTrackUnsubscribed: remoteParticipant: %s, audio: %s, enabled: %b, " - + "subscribed: %b", + "onAudioTrackUnsubscribed: remoteParticipant: %s, audio: %s, enabled: %b, subscribed: %b", remoteParticipant.getIdentity(), remoteAudioTrackPublication.getTrackSid(), remoteAudioTrackPublication.isTrackEnabled(), remoteAudioTrackPublication.isTrackSubscribed()); - boolean newAudioState = true; - if (participantController.getPrimaryItem().sid.equals(remoteParticipant.getSid())) { // update audio state for primary view - participantController.getPrimaryItem().muted = newAudioState; - participantController.getPrimaryView().setMuted(newAudioState); + participantController.getPrimaryItem().muted = true; + participantController.getPrimaryView().setMuted(true); } else { // update thumbs with audio state - participantController.updateThumbs(remoteParticipant.getSid(), newAudioState); + participantController.updateThumbs(remoteParticipant.getSid(), true); } } @@ -1719,8 +1721,7 @@ public void onVideoTrackSubscribed( @NonNull RemoteVideoTrackPublication remoteVideoTrackPublication, @NonNull RemoteVideoTrack remoteVideoTrack) { Timber.i( - "onVideoTrackSubscribed: remoteParticipant: %s, video: %s, enabled: %b, " - + "subscribed: %b", + "onVideoTrackSubscribed: remoteParticipant: %s, video: %s, enabled: %b, subscribed: %b", remoteParticipant.getIdentity(), remoteVideoTrackPublication.getTrackSid(), remoteVideoTrackPublication.isTrackEnabled(), @@ -1750,8 +1751,7 @@ public void onVideoTrackSubscriptionFailed( @NonNull RemoteVideoTrackPublication remoteVideoTrackPublication, @NonNull TwilioException twilioException) { Timber.w( - "onVideoTrackSubscriptionFailed: remoteParticipant: %s, video: %s, " - + "exception: %s", + "onVideoTrackSubscriptionFailed: remoteParticipant: %s, video: %s, exception: %s", remoteParticipant.getIdentity(), remoteVideoTrackPublication.getTrackSid(), twilioException.getMessage()); @@ -1833,8 +1833,7 @@ public void onDataTrackSubscribed( @NonNull RemoteDataTrackPublication remoteDataTrackPublication, @NonNull RemoteDataTrack remoteDataTrack) { Timber.i( - "onDataTrackSubscribed: remoteParticipant: %s, data: %s, enabled: %b, " - + "subscribed: %b", + "onDataTrackSubscribed: remoteParticipant: %s, data: %s, enabled: %b, subscribed: %b", remoteParticipant.getIdentity(), remoteDataTrackPublication.getTrackSid(), remoteDataTrackPublication.isTrackEnabled(), @@ -1847,8 +1846,7 @@ public void onDataTrackSubscriptionFailed( @NonNull RemoteDataTrackPublication remoteDataTrackPublication, @NonNull TwilioException twilioException) { Timber.w( - "onDataTrackSubscriptionFailed: remoteParticipant: %s, video: %s, " - + "exception: %s", + "onDataTrackSubscriptionFailed: remoteParticipant: %s, video: %s, exception: %s", remoteParticipant.getIdentity(), remoteDataTrackPublication.getTrackSid(), twilioException.getMessage()); @@ -1863,8 +1861,7 @@ public void onDataTrackUnsubscribed( @NonNull RemoteDataTrackPublication remoteDataTrackPublication, @NonNull RemoteDataTrack remoteDataTrack) { Timber.i( - "onDataTrackUnsubscribed: remoteParticipant: %s, data: %s, enabled: %b, " - + "subscribed: %b", + "onDataTrackUnsubscribed: remoteParticipant: %s, data: %s, enabled: %b, subscribed: %b", remoteParticipant.getIdentity(), remoteDataTrackPublication.getTrackSid(), remoteDataTrackPublication.isTrackEnabled(), diff --git a/app/src/main/java/com/twilio/video/app/ui/room/RoomActivityModule.java b/app/src/main/java/com/twilio/video/app/ui/room/RoomActivityModule.java index 3b335ad08..deea13a19 100644 --- a/app/src/main/java/com/twilio/video/app/ui/room/RoomActivityModule.java +++ b/app/src/main/java/com/twilio/video/app/ui/room/RoomActivityModule.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/ui/room/RoomActivitySubcomponent.java b/app/src/main/java/com/twilio/video/app/ui/room/RoomActivitySubcomponent.java index 5634025b2..f24db34c2 100644 --- a/app/src/main/java/com/twilio/video/app/ui/room/RoomActivitySubcomponent.java +++ b/app/src/main/java/com/twilio/video/app/ui/room/RoomActivitySubcomponent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/ui/settings/SettingsActivity.java b/app/src/main/java/com/twilio/video/app/ui/settings/SettingsActivity.java index 497c517a7..4f2ff4356 100644 --- a/app/src/main/java/com/twilio/video/app/ui/settings/SettingsActivity.java +++ b/app/src/main/java/com/twilio/video/app/ui/settings/SettingsActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,14 +20,12 @@ import android.content.SharedPreferences; import android.os.Bundle; import android.view.MenuItem; - import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceManager; - import com.twilio.video.AudioCodec; import com.twilio.video.G722Codec; import com.twilio.video.H264Codec; @@ -82,13 +80,11 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { @Override public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - default: - return super.onOptionsItemSelected(item); + if (item.getItemId() == android.R.id.home) { + finish(); + return true; } + return super.onOptionsItemSelected(item); } private void logout() { @@ -165,7 +161,7 @@ public void onDisplayPreferenceDialog(Preference preference) { if (dialogFragment != null) { dialogFragment.setTargetFragment(this, 0); - dialogFragment.show(getFragmentManager(), PREFERENCE_FRAGMENT_TAG); + dialogFragment.show(requireFragmentManager(), PREFERENCE_FRAGMENT_TAG); } } else { diff --git a/app/src/main/java/com/twilio/video/app/ui/settings/SettingsActivityModule.java b/app/src/main/java/com/twilio/video/app/ui/settings/SettingsActivityModule.java index 2695130d6..040f57568 100644 --- a/app/src/main/java/com/twilio/video/app/ui/settings/SettingsActivityModule.java +++ b/app/src/main/java/com/twilio/video/app/ui/settings/SettingsActivityModule.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/ui/settings/SettingsActivitySubcomponent.java b/app/src/main/java/com/twilio/video/app/ui/settings/SettingsActivitySubcomponent.java index b0752571f..be4f05d0c 100644 --- a/app/src/main/java/com/twilio/video/app/ui/settings/SettingsActivitySubcomponent.java +++ b/app/src/main/java/com/twilio/video/app/ui/settings/SettingsActivitySubcomponent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/ui/splash/SplashActivity.java b/app/src/main/java/com/twilio/video/app/ui/splash/SplashActivity.java index 36d9f334d..f82696c79 100644 --- a/app/src/main/java/com/twilio/video/app/ui/splash/SplashActivity.java +++ b/app/src/main/java/com/twilio/video/app/ui/splash/SplashActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,7 @@ import android.content.Intent; import android.os.Bundle; - import androidx.annotation.Nullable; - import com.twilio.video.app.auth.Authenticator; import com.twilio.video.app.base.BaseActivity; import com.twilio.video.app.ui.room.RoomActivity; diff --git a/app/src/main/java/com/twilio/video/app/ui/splash/SplashActivityModule.java b/app/src/main/java/com/twilio/video/app/ui/splash/SplashActivityModule.java index 8d2a552e4..ccc438a9c 100644 --- a/app/src/main/java/com/twilio/video/app/ui/splash/SplashActivityModule.java +++ b/app/src/main/java/com/twilio/video/app/ui/splash/SplashActivityModule.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/ui/splash/SplashActivitySubcomponent.java b/app/src/main/java/com/twilio/video/app/ui/splash/SplashActivitySubcomponent.java index f3149ee08..ec4ebb578 100644 --- a/app/src/main/java/com/twilio/video/app/ui/splash/SplashActivitySubcomponent.java +++ b/app/src/main/java/com/twilio/video/app/ui/splash/SplashActivitySubcomponent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/util/AuthHelper.java b/app/src/main/java/com/twilio/video/app/util/AuthHelper.java index f9dbd474a..fac647bf4 100644 --- a/app/src/main/java/com/twilio/video/app/util/AuthHelper.java +++ b/app/src/main/java/com/twilio/video/app/util/AuthHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,9 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.content.Context; - import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; - import com.google.android.gms.auth.api.Auth; import com.google.android.gms.auth.api.signin.GoogleSignInAccount; import com.google.android.gms.auth.api.signin.GoogleSignInOptions; @@ -36,6 +34,7 @@ import com.twilio.video.app.R; import java.lang.annotation.Retention; +// TODO Remove this class as part of this ticket https://issues.corp.twilio.com/browse/AHOYAPPS-63 public class AuthHelper { @Retention(SOURCE) @@ -76,7 +75,6 @@ public static void signInWithGoogle( task -> { if (!task.isSuccessful()) { errorListener.onError(ERROR_AUTHENTICATION_FAILED); - return; } }); } else { @@ -102,7 +100,6 @@ public static void signInWithEmail( task -> { if (!task.isSuccessful()) { errorListener.onError(ERROR_AUTHENTICATION_FAILED); - return; } }); } @@ -117,15 +114,12 @@ public static void signOut( public static GoogleApiClient buildGoogleAPIClient( final FragmentActivity activity, final ErrorListener errorListener) { - GoogleApiClient client = - new GoogleApiClient.Builder(activity) - .enableAutoManage( - activity, - connectionResult -> - errorListener.onError(ERROR_GOOGLE_PLAY_SERVICE_ERROR)) - .addApi(Auth.GOOGLE_SIGN_IN_API, buildGoogleSignInOptions(activity)) - .build(); - return client; + return new GoogleApiClient.Builder(activity) + .enableAutoManage( + activity, + connectionResult -> errorListener.onError(ERROR_GOOGLE_PLAY_SERVICE_ERROR)) + .addApi(Auth.GOOGLE_SIGN_IN_API, buildGoogleSignInOptions(activity)) + .build(); } private static GoogleSignInOptions buildGoogleSignInOptions(final FragmentActivity activity) { diff --git a/app/src/main/java/com/twilio/video/app/util/BuildConfigUtils.java b/app/src/main/java/com/twilio/video/app/util/BuildConfigUtils.java index 461d777be..bc1adf0b4 100644 --- a/app/src/main/java/com/twilio/video/app/util/BuildConfigUtils.java +++ b/app/src/main/java/com/twilio/video/app/util/BuildConfigUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,18 +19,12 @@ import com.twilio.video.app.BuildConfig; public class BuildConfigUtils { - private static final String INTERNAL_FLAVOR = "internal"; - private static final String DEVELOPMENT_FLAVOR = "development"; - public static boolean isDevelopmentFlavor() { - return BuildConfig.FLAVOR.equals(DEVELOPMENT_FLAVOR); + public static boolean isCommunityFlavor() { + return BuildConfig.FLAVOR.equals("community"); } public static boolean isInternalFlavor() { - return BuildConfig.FLAVOR.equals(INTERNAL_FLAVOR); - } - - public static boolean isInternalRelease() { - return isInternalFlavor() && !BuildConfig.DEBUG; + return BuildConfig.FLAVOR.equals("internal"); } } diff --git a/app/src/main/java/com/twilio/video/app/util/CameraCapturerCompat.java b/app/src/main/java/com/twilio/video/app/util/CameraCapturerCompat.java index 6f4a2fb7b..7f135c2b3 100644 --- a/app/src/main/java/com/twilio/video/app/util/CameraCapturerCompat.java +++ b/app/src/main/java/com/twilio/video/app/util/CameraCapturerCompat.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,7 @@ import android.content.Context; import android.util.Pair; - import androidx.annotation.NonNull; - import com.twilio.video.Camera2Capturer; import com.twilio.video.CameraCapturer; import com.twilio.video.VideoCapturer; @@ -35,27 +33,28 @@ public class CameraCapturerCompat { private Camera2Capturer camera2Capturer; private Pair frontCameraPair; private Pair backCameraPair; - private final Camera2Capturer.Listener camera2Listener = - new Camera2Capturer.Listener() { - @Override - public void onFirstFrameAvailable() { - Timber.i("onFirstFrameAvailable"); - } - - @Override - public void onCameraSwitched(@NonNull String newCameraId) { - Timber.i("onCameraSwitched: newCameraId = %s", newCameraId); - } - - @Override - public void onError(@NonNull Camera2Capturer.Exception camera2CapturerException) { - Timber.e(camera2CapturerException.getMessage()); - } - }; public CameraCapturerCompat(Context context, CameraCapturer.CameraSource cameraSource) { if (Camera2Capturer.isSupported(context)) { setCameraPairs(context); + Camera2Capturer.Listener camera2Listener = + new Camera2Capturer.Listener() { + @Override + public void onFirstFrameAvailable() { + Timber.i("onFirstFrameAvailable"); + } + + @Override + public void onCameraSwitched(@NonNull String newCameraId) { + Timber.i("onCameraSwitched: newCameraId = %s", newCameraId); + } + + @Override + public void onError( + @NonNull Camera2Capturer.Exception camera2CapturerException) { + Timber.e(camera2CapturerException); + } + }; camera2Capturer = new Camera2Capturer(context, getCameraId(cameraSource), camera2Listener); } else { diff --git a/app/src/main/java/com/twilio/video/app/util/CrashlyticsTreeRanger.java b/app/src/main/java/com/twilio/video/app/util/CrashlyticsTreeRanger.java index a76ec6327..012ac658c 100644 --- a/app/src/main/java/com/twilio/video/app/util/CrashlyticsTreeRanger.java +++ b/app/src/main/java/com/twilio/video/app/util/CrashlyticsTreeRanger.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/util/DebugTree.java b/app/src/main/java/com/twilio/video/app/util/DebugTree.java index 6a674ce85..d5637a8a5 100644 --- a/app/src/main/java/com/twilio/video/app/util/DebugTree.java +++ b/app/src/main/java/com/twilio/video/app/util/DebugTree.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.twilio.video.app.util; import android.util.Log; +import org.jetbrains.annotations.NotNull; import timber.log.Timber; public class DebugTree extends Timber.DebugTree { @@ -27,7 +28,7 @@ public DebugTree(TreeRanger treeRanger) { } @Override - protected void log(int priority, String tag, String message, Throwable throwable) { + protected void log(int priority, String tag, @NotNull String message, Throwable throwable) { // Always log in debug super.log(priority, tag, message, throwable); diff --git a/app/src/main/java/com/twilio/video/app/util/EnvUtil.java b/app/src/main/java/com/twilio/video/app/util/EnvUtil.java index e5a770290..8a568fc9b 100644 --- a/app/src/main/java/com/twilio/video/app/util/EnvUtil.java +++ b/app/src/main/java/com/twilio/video/app/util/EnvUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.twilio.video.app.util; - import static com.twilio.video.app.data.api.TwilioApiEnvironmentKt.TWILIO_API_DEV_ENV; import static com.twilio.video.app.data.api.TwilioApiEnvironmentKt.TWILIO_API_STAGE_ENV; @@ -27,12 +26,14 @@ public class EnvUtil { public static final String TWILIO_ENV_KEY = "TWILIO_ENVIRONMENT"; public static String getNativeEnvironmentVariableValue(String environment) { - if (environment.equals(TWILIO_API_DEV_ENV)) { - return TWILIO_DEV_ENV; - } else if (environment.equals(TWILIO_API_STAGE_ENV)) { - return TWILIO_STAGE_ENV; - } else { - return TWILIO_PROD_ENV; + if (environment != null) { + if (environment.equals(TWILIO_API_DEV_ENV)) { + return TWILIO_DEV_ENV; + } else if (environment.equals(TWILIO_API_STAGE_ENV)) { + return TWILIO_STAGE_ENV; + } } + + return TWILIO_PROD_ENV; } } diff --git a/app/src/main/java/com/twilio/video/app/util/IceOptionsHelper.java b/app/src/main/java/com/twilio/video/app/util/IceOptionsHelper.java index 13ee0e87b..df838bc38 100644 --- a/app/src/main/java/com/twilio/video/app/util/IceOptionsHelper.java +++ b/app/src/main/java/com/twilio/video/app/util/IceOptionsHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,50 +18,12 @@ import android.util.SparseBooleanArray; import android.widget.ListView; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; -import com.twilio.video.IceServer; -import com.twilio.video.IceTransportPolicy; import com.twilio.video.app.model.TwilioIceServer; -import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; public class IceOptionsHelper { - private static Type listType = new TypeToken>() {}.getType(); - - public static List convertToTwilioIceServerList(String json) { - if (json == null || json.equals("")) { - return new ArrayList<>(); - } - Gson gson = new GsonBuilder().create(); - return gson.fromJson(json, listType); - } - - public static String convertToJson(List twilioIceServers) { - Gson gson = new GsonBuilder().create(); - return gson.toJson(twilioIceServers, listType); - } - - public static Set convertToIceServersSet(List twilioIceServers) { - Set result = new HashSet<>(); - if (twilioIceServers != null && twilioIceServers.size() > 0) { - for (TwilioIceServer twilioIceServer : twilioIceServers) { - IceServer iceServer = - new IceServer( - twilioIceServer.getUrl(), - twilioIceServer.getUsername(), - twilioIceServer.getCredential()); - result.add(iceServer); - } - } - return result; - } - public static List getSelectedServersFromListView( ListView iceServersListView) { List selectedServers = new ArrayList<>(); @@ -76,11 +38,4 @@ public static List getSelectedServersFromListView( } return selectedServers; } - - public static IceTransportPolicy convertToIceTransportPolicy(String iceTransportStr) { - if (iceTransportStr.equalsIgnoreCase("relay")) { - return IceTransportPolicy.RELAY; - } - return IceTransportPolicy.ALL; - } } diff --git a/app/src/main/java/com/twilio/video/app/util/InputUtils.java b/app/src/main/java/com/twilio/video/app/util/InputUtils.java index f17820174..e1f382c0d 100644 --- a/app/src/main/java/com/twilio/video/app/util/InputUtils.java +++ b/app/src/main/java/com/twilio/video/app/util/InputUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/src/main/java/com/twilio/video/app/util/ReleaseTree.java b/app/src/main/java/com/twilio/video/app/util/ReleaseTree.java index c2ec5cde6..0c60d2c2d 100644 --- a/app/src/main/java/com/twilio/video/app/util/ReleaseTree.java +++ b/app/src/main/java/com/twilio/video/app/util/ReleaseTree.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.twilio.video.app.util; import android.util.Log; +import org.jetbrains.annotations.NotNull; import timber.log.Timber; public class ReleaseTree extends Timber.Tree { @@ -27,7 +28,7 @@ public ReleaseTree(TreeRanger treeRanger) { } @Override - protected void log(int priority, String tag, String message, Throwable throwable) { + protected void log(int priority, String tag, @NotNull String message, Throwable throwable) { // No logging in release, but we allow the ranger to still act switch (priority) { case Log.VERBOSE: diff --git a/app/src/main/java/com/twilio/video/app/util/StatsScheduler.java b/app/src/main/java/com/twilio/video/app/util/StatsScheduler.java index f0205f450..a5d39f492 100644 --- a/app/src/main/java/com/twilio/video/app/util/StatsScheduler.java +++ b/app/src/main/java/com/twilio/video/app/util/StatsScheduler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,7 @@ import android.os.Handler; import android.os.HandlerThread; - import androidx.annotation.NonNull; - import com.twilio.video.Room; import com.twilio.video.StatsListener; diff --git a/app/src/main/java/com/twilio/video/app/util/TreeRanger.java b/app/src/main/java/com/twilio/video/app/util/TreeRanger.java index 874e8db6e..efed53f90 100644 --- a/app/src/main/java/com/twilio/video/app/util/TreeRanger.java +++ b/app/src/main/java/com/twilio/video/app/util/TreeRanger.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Twilio, Inc. + * Copyright (C) 2019 Twilio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ package com.twilio.video.app.util; -public interface TreeRanger { +interface TreeRanger { void inform(String message); void caution(String message); diff --git a/build.gradle b/build.gradle index 334f57e41..bc2517500 100644 --- a/build.gradle +++ b/build.gradle @@ -1,49 +1,57 @@ buildscript { - apply from: "$rootProject.projectDir/common.gradle" - ext.kotlin_version='1.3.41' ext.versions = [ - // Android - 'compileSdk': 28, - 'buildTools': '28.0.3', - 'minSdk': 16, - 'targetSdk': 28, + 'butterknife' : '10.2.0', + ] - // Plugins - 'androidGradlePlugin': '3.5.0', - 'googleServices': '3.2.1', - 'fabricPlugin': '1.31.0', + ext.keystore = (project.hasProperty('androidKeystore') ? + project.property('androidKeystore') : '/fake/path/to/keystore') + ext.keystorePassword = (project.hasProperty('androidKeystorePassword') ? + project.property('androidKeystorePassword') : 'fakepassword') + ext.releaseKeyAlias = (project.hasProperty('androidReleaseKeyAlias') ? + project.property('androidReleaseKeyAlias') : 'fakealias') + ext.releaseKeyPassword = (project.hasProperty('androidReleaseKeyPassword') ? + project.property('androidReleaseKeyPassword') : 'fakepassword') - // Java - 'java': JavaVersion.VERSION_1_8, + ext.getBintrayUsername = { + def bintrayUsername = System.getenv("BINTRAY_USERNAME") + + if (bintrayUsername == null) { + logger.log(LogLevel.INFO, "Could not locate BINTRAY_USERNAME environment variable. " + + "Trying local.properties") + Properties properties = new Properties() + if (project.rootProject.file('local.properties').exists()) { + properties.load(project.rootProject.file('local.properties').newDataInputStream()) + bintrayUsername = properties.getProperty('BINTRAY_USERNAME') + } + } + + if (bintrayUsername == null) { + logger.log(LogLevel.WARN, "Bintray username unavailable.") + } + + return bintrayUsername + } + + ext.getBintrayPassword = { + def bintrayPassword = System.getenv("BINTRAY_PASSWORD") + + if (bintrayPassword == null) { + logger.log(LogLevel.INFO, "Could not locate BINTRAY_PASSWORD environment variable. " + + "Trying local.properties") + Properties properties = new Properties() + if (project.rootProject.file('local.properties').exists()) { + properties.load(project.rootProject.file('local.properties').newDataInputStream()) + bintrayPassword = properties.getProperty('BINTRAY_PASSWORD') + } + } + + if (bintrayPassword == null) { + logger.log(LogLevel.WARN, "Bintray password unavailable.") + } + + return bintrayPassword + } - // Dependencies - 'junit': '4.12', - 'mockito': '1.10.19', - 'guava': '19.0', - 'retrofit': '1.9.0', - 'supportLibrary': '27.1.1', - 'espresso': '3.0.0', - 'testSupportLibrary': '1.0.0', - 'uiAutomator': '2.1.2', - 'gson': '2.7', - 'apacheCommons': '3.6', - 'junitParams': '1.1.1', - 'relinker': '1.2.2', - 'jjwt': '0.7.0', - 'materialrangebar': '1.3', - 'butterknife': '9.0.0', - 'multidex': '1.0.3', - 'firebase': '16.0.1', - 'firebaseAuth': '16.0.2', - 'crashlytics': '2.9.5', - 'playServices': '15.0.1', - 'playServicesAuth': '15.0.1', - 'dagger': '2.10', - 'rxJava2': '2.0.6', - 'rxJava2Adapter': '1.0.0', - 'rxAndroid2': '2.0.1', - 'retrofit2': '2.1.0' - ] repositories { google() jcenter() @@ -70,11 +78,11 @@ buildscript { } } dependencies { - classpath "com.android.tools.build:gradle:${versions.androidGradlePlugin}" + classpath "com.android.tools.build:gradle:3.5.2" classpath "com.jakewharton:butterknife-gradle-plugin:${versions.butterknife}" - classpath "com.google.gms:google-services:${versions.googleServices}" - classpath "io.fabric.tools:gradle:${versions.fabricPlugin}" - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "com.google.gms:google-services:4.3.2" + classpath "io.fabric.tools:gradle:1.31.0" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50" } } @@ -94,10 +102,13 @@ spotless { target '**/*.java' googleJavaFormat().aosp() } + kotlin { + target '**/*.kt' + ktlint() + } } allprojects { - apply from: "$rootProject.projectDir/common.gradle" repositories { google() jcenter() @@ -124,587 +135,3 @@ allprojects { } } } - -task validateReleaseCandidateTag { - description = 'Validate the release candidate tag matches the release candidate version ' + - 'present on commit' - group = 'Git' - - doLast { - def circleTag = System.getenv("CIRCLE_TAG") - def tagsMatch = (matchesRcVersion( circleTag)) ? ("true") : ("false") - - exec { - workingDir "${rootDir}" - commandLine tagsMatch - } - } -} - -task validateReleaseTag { - description = 'Validate the release tag matches the release version ' + - 'present on commit' - group = 'Git' - - doLast { - def circleTag = System.getenv("CIRCLE_TAG") - def tagsMatch = (matchesVersion(circleTag)) ? ("true") : ("false") - - exec { - workingDir "${rootDir}" - commandLine tagsMatch - } - } -} - -task incrementRc { - description = 'Increment the current release candidate version' - group = 'Git' - - dependsOn 'validateReleaseCandidateTag' - - doLast { - def stdOut = new ByteArrayOutputStream() - exec { - commandLine "bash", "-c", "git remote show origin | grep HEAD | cut -d: -f2-" - standardOutput stdOut - } - println("DEFAULT BRANCH = " + stdOut.toString()) - def gitBranch = stdOut.toString().replaceAll("\\s","") - def circleTag = System.getenv("CIRCLE_TAG") - def githubToken = System.getenv("GITHUB_TOKEN") - def repoSlug = "${System.env.CIRCLE_PROJECT_USERNAME}/${System.env.CIRCLE_PROJECT_REPONAME}" - def gitRef = "https://${githubToken}@github.com/${repoSlug}.git" - def remote = "upstream" - def pushNullFile = new FileOutputStream("/dev/null") - def nextVersionRc = "${versionRc + 1}" - // Create build directory if not created - if (!buildDir.exists()) { - buildDir.mkdir() - } - def tmpProjectPropertiesFile = new FileOutputStream("${buildDir}/gradle.properties") - - exec { - workingDir "${rootDir}" - commandLine "git", "remote", "add", "${remote}", "${gitRef}" - // Ignore exit value because remote may have been added in previous task - ignoreExitValue true - } - - exec { - workingDir "${rootDir}" - commandLine "git", "fetch", "${remote}" - } - - // Ignore gitBranch checked out by circle and use latest from next command - exec { - workingDir "${rootDir}" - commandLine "git", "branch", "-D", "${gitBranch}" - ignoreExitValue true - } - - exec { - workingDir "${rootDir}" - commandLine "git", "checkout", "-b", "${gitBranch}", "remotes/${remote}/${gitBranch}" - } - - /* - * Only update the RC version on upstream branch if the version matches tag. It is possible - * these values do not match if an RC job is performed on an earlier commit and a PR - * with a version update occurs later in history. - */ - if (matchesRcVersion(circleTag)) { - exec { - workingDir "${rootDir}" - commandLine "echo", "Incrementing RC from ${versionRc} to ${nextVersionRc}" - } - - exec { - workingDir "${rootDir}" - commandLine "sed", - "s@versionRc=.*@versionRc=${nextVersionRc}@", - "gradle.properties" - standardOutput tmpProjectPropertiesFile - } - - exec { - workingDir "${rootDir}" - commandLine "mv", "${buildDir}/gradle.properties", "gradle.properties" - } - - exec { - workingDir "${rootDir}" - commandLine "git", "commit", "gradle.properties", "-m", "\"Bump RC version [skip ci]\"" - } - - exec { - workingDir "${rootDir}" - commandLine "git", "push", "--quiet", "${remote}", "${gitBranch}" - standardOutput pushNullFile - } - } - } -} - -task incrementVersionAfterRelease { - description = 'Increment the SDK version after a release' - group = 'Git' - - doLast { - def stdOut = new ByteArrayOutputStream() - exec { - commandLine "bash", "-c", "git remote show origin | grep HEAD | cut -d: -f2-" - standardOutput stdOut - } - println("DEFAULT BRANCH = " + stdOut.toString()) - - def gitBranch = stdOut.toString().replaceAll("\\s","") - def circleTag = System.getenv("CIRCLE_TAG") - def githubToken = System.getenv("GITHUB_TOKEN") - def repoSlug = "${System.env.CIRCLE_PROJECT_USERNAME}/${System.env.CIRCLE_PROJECT_REPONAME}" - def gitRef = "https://${githubToken}@github.com/${repoSlug}.git" - def remote = "upstream" - def pushNullFile = new FileOutputStream("/dev/null") - def nextVersionPatch = versionPatch + 1 - // Create build directory if not created - if (!buildDir.exists()) { - buildDir.mkdir() - } - - exec { - workingDir "${rootDir}" - commandLine "git", "remote", "add", "${remote}", "${gitRef}" - // Ignore exit value because remote may have been added in previous task - ignoreExitValue true - } - - exec { - workingDir "${rootDir}" - commandLine "git", "fetch", "${remote}" - } - - // Ignore gitBranch checked out by circle and use latest from next command - exec { - workingDir "${rootDir}" - commandLine "git", "branch", "-D", "${gitBranch}" - ignoreExitValue true - } - - exec { - workingDir "${rootDir}" - commandLine "git", "checkout", "-b", "${gitBranch}", "remotes/${remote}/${gitBranch}" - } - - /* - * Only update the version on upstream branch if the version matches tag. It is possible - * these values do not match if a job is performed on an earlier commit and a PR - * with a version update occurs later in history. - */ - if (matchesVersion(circleTag)) { - exec { - workingDir "${rootDir}" - commandLine "echo", "Incrementing from versionPatch ${versionPatch} to " + - "${nextVersionPatch}" - } - - exec { - workingDir "${rootDir}" - commandLine "sed", - "s@versionPatch=.*@versionPatch=${nextVersionPatch}@", - "gradle.properties" - standardOutput new FileOutputStream("${buildDir}/gradle.properties") - } - - exec { - workingDir "${rootDir}" - commandLine "mv", "${buildDir}/gradle.properties", "gradle.properties" - } - - exec { - workingDir "${rootDir}" - commandLine "echo", "Resetting versionRc to 1" - } - - exec { - workingDir "${rootDir}" - commandLine "sed", - "s@versionRc=.*@versionRc=1@", - "gradle.properties" - standardOutput new FileOutputStream("${buildDir}/gradle.properties") - } - - exec { - workingDir "${rootDir}" - commandLine "mv", "${buildDir}/gradle.properties", "gradle.properties" - } - - exec { - workingDir "${rootDir}" - commandLine "echo", "Resetting phaseNumber to 1" - } - - exec { - workingDir "${rootDir}" - commandLine "sed", - "s@phaseNumber=.*@phaseNumber=1@", - "gradle.properties" - standardOutput new FileOutputStream("${buildDir}/gradle.properties") - } - - exec { - workingDir "${rootDir}" - commandLine "mv", "${buildDir}/gradle.properties", "gradle.properties" - } - - exec { - workingDir "${rootDir}" - commandLine "git", "commit", "gradle.properties", "-m", "\"Bump patch and reset rc version [skip ci]\"" - } - - exec { - workingDir "${rootDir}" - commandLine "git", "push", "--quiet", "${remote}", "${gitBranch}" - standardOutput pushNullFile - } - } - } -} - -task incrementVersionAfterPreRelease { - description = 'Increment the SDK version after a pre-release' - group = 'Git' - - doLast { - def stdOut = new ByteArrayOutputStream() - exec { - commandLine "bash", "-c", "git remote show origin | grep HEAD | cut -d: -f2-" - standardOutput stdOut - } - println("DEFAULT BRANCH = " + stdOut.toString()) - def gitBranch = stdOut.toString().replaceAll("\\s","") - def circleTag = System.getenv("CIRCLE_TAG") - def githubToken = System.getenv("GITHUB_TOKEN") - def repoSlug = "${System.env.CIRCLE_PROJECT_USERNAME}/${System.env.CIRCLE_PROJECT_REPONAME}" - def gitRef = "https://${githubToken}@github.com/${repoSlug}.git" - def remote = "upstream" - def pushNullFile = new FileOutputStream("/dev/null") - def nextPhaseNumber = phaseNumber + 1 - // Create build directory if not created - if (!buildDir.exists()) { - buildDir.mkdir() - } - - exec { - workingDir "${rootDir}" - commandLine "git", "remote", "add", "${remote}", "${gitRef}" - // Ignore exit value because remote may have been added in previous task - ignoreExitValue true - } - - exec { - workingDir "${rootDir}" - commandLine "git", "fetch", "${remote}" - } - - // Ignore gitBranch checked out by circle and use latest from following command - exec { - workingDir "${rootDir}" - commandLine "git", "branch", "-D", "${gitBranch}" - ignoreExitValue true - } - - exec { - workingDir "${rootDir}" - commandLine "git", "checkout", "-b", "${gitBranch}", "remotes/${remote}/${gitBranch}" - } - - /* - * Only update the phase on upstream branch if the version matches tag. It is possible - * these values do not match if a job is performed on an earlier commit and a PR - * with a version update occurs later in history. - */ - if (matchesVersion(circleTag)) { - exec { - workingDir "${rootDir}" - commandLine "echo", "Incrementing from phaseNumber ${phaseNumber} to " + - "${nextPhaseNumber}" - } - - exec { - workingDir "${rootDir}" - commandLine "sed", - "s@phaseNumber=.*@phaseNumber=${nextPhaseNumber}@", - "gradle.properties" - standardOutput new FileOutputStream("${buildDir}/gradle.properties") - } - - exec { - workingDir "${rootDir}" - commandLine "mv", "${buildDir}/gradle.properties", "gradle.properties" - } - - exec { - workingDir "${rootDir}" - commandLine "git", "commit", "gradle.properties", "-m", "\"Bump phase number [skip ci]\"" - } - - exec { - workingDir "${rootDir}" - commandLine "git", "push", "--quiet", "${remote}", "${gitBranch}" - standardOutput pushNullFile - } - } - } -} - -task incrementVersion(type: GradleBuild) { - description = 'Increment the SDK version' - group = 'Git' - dependsOn validateReleaseTag - def releaseVersion = System.getenv("CIRCLE_TAG") == null ? - ("") : - (System.getenv("CIRCLE_TAG")) - def incrementVersionTask = releaseVersion.contains("preview") || - releaseVersion.contains("beta") ? - ('incrementVersionAfterPreRelease') : - ('incrementVersionAfterRelease') - tasks = [incrementVersionTask] -} - -task publishLibraryJavadocs { - description = 'Publish Video Android Javadocs to gh-pages branch' - group = 'Publishing' - dependsOn validateReleaseTag - dependsOn 'library:createJavadocs' - def releaseVersion = System.getenv("CIRCLE_TAG") == null ? - ("") : - (System.getenv("CIRCLE_TAG")) - boolean preRelease = releaseVersion.contains("preview") || releaseVersion.contains("beta") - def pinLatestDocsCommand = preRelease ? - // Pin command is a no-op for pre releases - (["true"]) : - (["ln", "-sfn", "${releaseVersion}", "docs/latest"]) - def githubToken = System.getenv("GITHUB_TOKEN") - def repoSlug = "${System.env.CIRCLE_PROJECT_USERNAME}/${System.env.CIRCLE_PROJECT_REPONAME}" - def gitRef = "https://${githubToken}@github.com/${repoSlug}.git" - def remote = "upstream" - def pushNullFile = new FileOutputStream("/dev/null") - - doLast { - exec { - workingDir "${rootDir}" - commandLine "git", "remote", "add", "${remote}", "${gitRef}" - // Ignore exit value because remote may have been added in previous task - ignoreExitValue true - } - - exec { - workingDir "${rootDir}" - commandLine "git", "fetch", "${remote}" - } - - exec { - workingDir "${rootDir}" - commandLine "git", "checkout", "-b", "gh-pages", "remotes/${remote}/gh-pages" - } - - exec { - workingDir "${rootDir}" - commandLine "mv", "library/build/docs/javadoc", "docs/${releaseVersion}" - } - - exec { - workingDir "${rootDir}" - commandLine pinLatestDocsCommand - } - - exec { - workingDir "${rootDir}" - commandLine "git", "add", "docs/${releaseVersion}", "docs/latest" - } - - exec { - workingDir "${rootDir}" - commandLine "git", "commit", "-m", "\"${releaseVersion} release docs [skip ci]\"" - } - - exec { - workingDir "${rootDir}" - commandLine "git", "push", "--quiet", "${remote}", "gh-pages" - standardOutput pushNullFile - } - - exec { - workingDir "${rootDir}" - commandLine "git", "checkout", "${releaseVersion}" - } - } -} - -/* - * Any tests that are network intensive are run on virtual devices because they do not run - * on the same congested network as physical devices. Running select tests on virtual devices - * ensures a more stable CI test execution and prevents test runs from exceeding the - * Firebase Test Lab physical device 30 minute time limit. - */ - -task firebaseTestLabCheckLibraryCamera(type: Exec) { - description = 'Runs library instrumentation tests that use camera on Firebase Test Lab' - group = 'Test' - dependsOn 'library:assembleDebugAndroidTest' - commandLine 'gcloud', - 'firebase', - 'test', - 'android', - 'run', - '--no-record-video', - '--project', - 'video-app-79418', - '--async', - 'video-app-args.yaml:integration-capturer-tests' -} - -task librarySizeReport(type: GradleBuild) { - description = 'Calculate Video Android SDK Size Impact' - group = 'Analyze' - - buildFile = file('apkscale/build.gradle') - tasks = ['clean', 'assembleRelease'] - startParameter.projectProperties += gradle.startParameter.projectProperties - - doLast { - def videoAndroidSizeReport = "Size Report\n" + - "\n" + - "| ABI | APK Size Impact |\n" + - "| --------------- | --------------- |\n" - def apkSizeImpactMap = [:] - ["universal", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"].each { arch -> - def outputStream = new ByteArrayOutputStream() - - // Perform diff between APK with and without Video Android SDK - exec { - workingDir "${rootDir}" - commandLine "apkanalyzer", - '--human-readable', - 'apk', - 'compare', - '--different-only', - "apkscale/build/outputs/apk/withoutVideoSdk/release/apkscale-" + - "withoutVideoSdk-${arch}-release-unsigned.apk", - "apkscale/build/outputs/apk/withVideoSdk/release/apkscale-withVideoSdk-" + - "${arch}-release-unsigned.apk" - standardOutput outputStream - } - - /* - * The line format of apkanalyzer is - * - * old size / new size / size difference / path - * - * The first line represents the difference between the entire APKs followed by file - * and directory differrences. Extract the total size difference to determine the APK - * size impact. - */ - def apkSizeImpact = outputStream.toString().split()[2] - - // Cache impact in table - apkSizeImpactMap.put(arch, apkSizeImpact) - } - - // Build out the table - apkSizeImpactMap.each { arch, apkSizeImpact -> - videoAndroidSizeReport += "| ${arch.padRight(16)}| ${apkSizeImpact.padRight(16)}|\n" - - } - - // Print report - println(videoAndroidSizeReport) - - // Post PR comment with report - def repoSlug = "${System.env.CIRCLE_PROJECT_USERNAME}/${System.env.CIRCLE_PROJECT_REPONAME}" - if (System.env.CIRCLE_PULL_REQUEST) { - def githubPullRequestNumber = Arrays.asList( - System.env.CIRCLE_PULL_REQUEST.split("/")).last() - def githubPullRequestUrl = new URL("https://api.github.com/repos/" + - "${repoSlug}/issues/${githubPullRequestNumber}/comments") - exec { - workingDir "${rootDir}" - commandLine "curl", - "-H", "Authorization: token ${System.env.GITHUB_TOKEN}", - "-X", 'POST', - // Escape new lines for json body - "-d", "{\"body\":\"${videoAndroidSizeReport.replace('\n', '\\n')}\"}", - "${githubPullRequestUrl}" - } - } - - // Append report to Github Release - if (System.env.CIRCLE_TAG) { - def githubReleasesTagUrl = new URL("https://api.github.com/repos/" + - "${repoSlug}/releases/tags/${System.env.CIRCLE_TAG}") - def githubReleasesUrlString = "https://api.github.com/repos/" + - "${repoSlug}/releases/" - def outputStream = new ByteArrayOutputStream() - - // Get the current release body - exec { - workingDir "${rootDir}" - commandLine "curl", - "-H", "Authorization: token ${System.env.GITHUB_TOKEN}", - "-X", 'GET', - "-s", - "${githubReleasesTagUrl}" - standardOutput outputStream - } - - // Append the size report to the release - def slurper = new groovy.json.JsonSlurper() - def releaseResponse = slurper.parseText(outputStream.toString()) - releaseResponse.body += "\n\n" + videoAndroidSizeReport - def githubReleasesUrl = new URL(githubReleasesUrlString + releaseResponse.id) - - exec { - workingDir "${rootDir}" - commandLine "curl", - "-H", "Authorization: token ${System.env.GITHUB_TOKEN}", - "-X", 'PATCH', - "-d", groovy.json.JsonOutput.toJson(releaseResponse), - "-s", - "${githubReleasesUrl}" - } - } - } -} - -/* - * Checks if a RC tag matches version and RC of current commit - */ -def matchesRcVersion(versionTag) { - def properties = new Properties() - file("${rootDir}/gradle.properties").withInputStream { properties.load(it) } - def rcTag = "${properties.getProperty("versionMajor")}." + - "${properties.getProperty("versionMinor")}." + - "${properties.getProperty("versionPatch")}-" + - "rc${properties.getProperty("versionRc")}" - - return rcTag == versionTag -} - -/* - * Checks if release tag matches version and current commit - */ -def matchesVersion(versionTag) { - def properties = new Properties() - boolean preRelease = versionTag.contains("preview") || versionTag.contains("beta") - file("${rootDir}/gradle.properties").withInputStream { properties.load(it) } - def releaseTag = "${properties.getProperty("versionMajor")}." + - "${properties.getProperty("versionMinor")}." + - "${properties.getProperty("versionPatch")}" - - if (preRelease) { - releaseTag += "-${properties.getProperty("phase").replaceAll("\"", "")}" + - "${properties.getProperty("phaseNumber")}" - } - - return releaseTag == versionTag -} diff --git a/common.gradle b/common.gradle deleted file mode 100644 index 42fba63d5..000000000 --- a/common.gradle +++ /dev/null @@ -1,56 +0,0 @@ -apply from: "$rootProject.projectDir/gradle.properties" - -/** - * Properties used for signing release builds. Note that these properties must be set in order - * to build proper releases. We set placeholder values so developers are not required to set these - * properties for local development - */ -// TODO Move all to project level build.gradle -ext.keystore = (project.hasProperty('androidKeystore') ? - project.property('androidKeystore') : '/fake/path/to/keystore') -ext.keystorePassword = (project.hasProperty('androidKeystorePassword') ? - project.property('androidKeystorePassword') : 'fakepassword') -ext.releaseKeyAlias = (project.hasProperty('androidReleaseKeyAlias') ? - project.property('androidReleaseKeyAlias') : 'fakealias') -ext.releaseKeyPassword = (project.hasProperty('androidReleaseKeyPassword') ? - project.property('androidReleaseKeyPassword') : 'fakepassword') - -ext.getBintrayUsername = { - def bintrayUsername = System.getenv("BINTRAY_USERNAME"); - - if (bintrayUsername == null) { - logger.log(LogLevel.INFO, "Could not locate BINTRAY_USERNAME environment variable. " + - "Trying local.properties") - Properties properties = new Properties() - if (project.rootProject.file('local.properties').exists()) { - properties.load(project.rootProject.file('local.properties').newDataInputStream()) - bintrayUsername = properties.getProperty('BINTRAY_USERNAME') - } - } - - if (bintrayUsername == null) { - logger.log(LogLevel.WARN, "Bintray username unavailable.") - } - - return bintrayUsername; -} - -ext.getBintrayPassword = { - def bintrayPassword = System.getenv("BINTRAY_PASSWORD"); - - if (bintrayPassword == null) { - logger.log(LogLevel.INFO, "Could not locate BINTRAY_PASSWORD environment variable. " + - "Trying local.properties") - Properties properties = new Properties() - if (project.rootProject.file('local.properties').exists()) { - properties.load(project.rootProject.file('local.properties').newDataInputStream()) - bintrayPassword = properties.getProperty('BINTRAY_PASSWORD') - } - } - - if (bintrayPassword == null) { - logger.log(LogLevel.WARN, "Bintray password unavailable.") - } - - return bintrayPassword; -} diff --git a/twilioapi/.gitignore b/twilioapi/.gitignore deleted file mode 100644 index 796b96d1c..000000000 --- a/twilioapi/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/twilioapi/build.gradle b/twilioapi/build.gradle deleted file mode 100644 index 2ceffd770..000000000 --- a/twilioapi/build.gradle +++ /dev/null @@ -1,37 +0,0 @@ -apply plugin: 'com.android.library' - -android { - compileSdkVersion versions.compileSdk - buildToolsVersion "${versions.buildTools}" - - lintOptions { - warningsAsErrors true - } - - defaultConfig { - minSdkVersion versions.minSdk - targetSdkVersion versions.targetSdk - versionCode 1 - versionName "1.0" - - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - } - - compileOptions { - sourceCompatibility versions.java - targetCompatibility versions.java - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - implementation "com.squareup.retrofit:retrofit:${versions.retrofit}" - androidTestImplementation "com.android.support.test.espresso:espresso-core:${versions.espresso}" - testImplementation "junit:junit:${versions.junit}" -} diff --git a/twilioapi/proguard-rules.pro b/twilioapi/proguard-rules.pro deleted file mode 100644 index e69de29bb..000000000 diff --git a/twilioapi/src/main/AndroidManifest.xml b/twilioapi/src/main/AndroidManifest.xml deleted file mode 100644 index fea9bfa9c..000000000 --- a/twilioapi/src/main/AndroidManifest.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/twilioapi/src/main/java/com/twilio/video/twilioapi/TwilioApiUtils.java b/twilioapi/src/main/java/com/twilio/video/twilioapi/TwilioApiUtils.java deleted file mode 100644 index 7e3643a91..000000000 --- a/twilioapi/src/main/java/com/twilio/video/twilioapi/TwilioApiUtils.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2017 Twilio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twilio.video.twilioapi; - -import android.util.Base64; -import com.google.gson.GsonBuilder; -import com.twilio.video.twilioapi.model.TwilioServiceToken; -import retrofit.Callback; -import retrofit.RestAdapter; -import retrofit.converter.GsonConverter; -import retrofit.http.Header; -import retrofit.http.POST; -import retrofit.http.Path; - -public class TwilioApiUtils { - private static final String PROD_BASE_URL = "https://api.twilio.com"; - private static final String STAGE_BASE_URL = "https://api.stage.twilio.com"; - private static final String DEV_BASE_URL = "https://api.dev.twilio.com"; - - public static final String PROD = "prod"; - public static final String STAGE = "stage"; - public static final String DEV = "dev"; - - private static String currentEnvironment = PROD; - - interface TwilioApiService { - @POST("/2010-04-01/Accounts/{accountSid}/Tokens.json") - void getServiceToken( - @Header("Authorization") String authorization, - @Path("accountSid") String accountSid, - Callback serviceTokenCallback); - - @POST("/2010-04-01/Accounts/{accountSid}/Tokens.json") - TwilioServiceToken getServiceToken( - @Header("Authorization") String authorization, - @Path("accountSid") String accountSid); - } - - private static TwilioApiService twilioApiService = createTwilioApiService(); - - private static TwilioApiService createTwilioApiService() { - String apiBaseUrl = PROD_BASE_URL; - if (currentEnvironment.equalsIgnoreCase(STAGE)) { - apiBaseUrl = STAGE_BASE_URL; - } else if (currentEnvironment.equalsIgnoreCase(DEV)) { - apiBaseUrl = DEV_BASE_URL; - } - return new RestAdapter.Builder() - .setEndpoint(apiBaseUrl) - .setConverter(new GsonConverter(new GsonBuilder().create())) - .build() - .create(TwilioApiService.class); - } - - public static void getServiceToken( - String accountSid, - String signingKeySid, - String signingKeySecret, - String environment, - Callback callback) - throws IllegalArgumentException { - if (!environment.equalsIgnoreCase(PROD) - && !environment.equalsIgnoreCase(STAGE) - && !environment.equalsIgnoreCase(DEV)) { - throw new IllegalArgumentException("Invalid Environment!"); - } - if (!currentEnvironment.equalsIgnoreCase(environment)) { - currentEnvironment = environment; - twilioApiService = createTwilioApiService(); - } - String authString = signingKeySid + ":" + signingKeySecret; - String authorization = - "Basic " + Base64.encodeToString(authString.getBytes(), Base64.NO_WRAP); - twilioApiService.getServiceToken(authorization, accountSid, callback); - } - - // Provide a synchronous version of getServiceToken for tests - public static TwilioServiceToken getServiceToken( - String accountSid, String signingKeySid, String signingKeySecret, String environment) { - if (!environment.equalsIgnoreCase(PROD) - && !environment.equalsIgnoreCase(STAGE) - && !environment.equalsIgnoreCase(DEV)) { - throw new IllegalArgumentException("Invalid Environment!"); - } - if (!currentEnvironment.equalsIgnoreCase(environment)) { - currentEnvironment = environment; - twilioApiService = createTwilioApiService(); - } - - String authString = signingKeySid + ":" + signingKeySecret; - String authorization = - "Basic " + Base64.encodeToString(authString.getBytes(), Base64.NO_WRAP); - - return twilioApiService.getServiceToken(authorization, accountSid); - } -} diff --git a/twilioapi/src/main/java/com/twilio/video/twilioapi/VideoApiUtils.java b/twilioapi/src/main/java/com/twilio/video/twilioapi/VideoApiUtils.java deleted file mode 100644 index e3f6bbab7..000000000 --- a/twilioapi/src/main/java/com/twilio/video/twilioapi/VideoApiUtils.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2017 Twilio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twilio.video.twilioapi; - -import android.util.Base64; -import android.util.Log; -import com.google.gson.GsonBuilder; -import com.twilio.video.twilioapi.model.VideoRoom; -import java.util.List; -import retrofit.Callback; -import retrofit.RestAdapter; -import retrofit.RetrofitError; -import retrofit.converter.GsonConverter; -import retrofit.http.Field; -import retrofit.http.FormUrlEncoded; -import retrofit.http.GET; -import retrofit.http.Header; -import retrofit.http.POST; -import retrofit.http.Path; - -public class VideoApiUtils { - private static final int MAX_RETRIES = 3; - private static final String PROD_BASE_URL = "https://video.twilio.com"; - private static final String STAGE_BASE_URL = "https://video.stage.twilio.com"; - private static final String DEV_BASE_URL = "https://video.dev.twilio.com"; - - public static final String PROD = "prod"; - public static final String STAGE = "stage"; - public static final String DEV = "dev"; - - public static final String P2P = "peer-to-peer"; - public static final String GROUP = "group"; - public static final String GROUP_SMALL = "group-small"; - - private static String currentEnvironment = PROD; - - interface VideoApiService { - @POST("/v1/Rooms") - @FormUrlEncoded - void createRoom( - @Header("Authorization") String authorization, - @Field("UniqueName") String name, - @Field("Type") String type, - @Field("EnableTurn") boolean enableTurn, - @Field("RecordParticipantsOnConnect") boolean enableRecording, - @Field("VideoCodecs") List videoCodecs, - @Field("region") String region, - @Field("media_region") String mediaRegion, - Callback videoRoomCallback); - - @POST("/v1/Rooms") - @FormUrlEncoded - VideoRoom createRoom( - @Header("Authorization") String authorization, - @Field("UniqueName") String name, - @Field("Type") String type, - @Field("EnableTurn") boolean enableTurn, - @Field("RecordParticipantsOnConnect") boolean enableRecording, - @Field("VideoCodecs") List videoCodecs, - @Field("region") String region, - @Field("media_region") String mediaRegion); - - @GET("/v1/Rooms/{unique_name}") - VideoRoom getRoom( - @Header("Authorization") String authorization, @Path("unique_name") String name); - - @POST("/v1/Rooms/{room_sid}") - @FormUrlEncoded - VideoRoom modifyRoom( - @Header("Authorization") String authorization, - @Path("room_sid") String roomSid, - @Field("Status") String status); - } - - private static VideoApiUtils.VideoApiService videoApiService = createVideoApiService(); - - private static VideoApiUtils.VideoApiService createVideoApiService() { - String apiBaseUrl = PROD_BASE_URL; - if (currentEnvironment.equalsIgnoreCase(STAGE)) { - apiBaseUrl = STAGE_BASE_URL; - } else if (currentEnvironment.equalsIgnoreCase(DEV)) { - apiBaseUrl = DEV_BASE_URL; - } - return new RestAdapter.Builder() - .setEndpoint(apiBaseUrl) - .setConverter(new GsonConverter(new GsonBuilder().create())) - .setLogLevel(RestAdapter.LogLevel.NONE) - .build() - .create(VideoApiUtils.VideoApiService.class); - } - - public static void createRoom( - String accountSid, - String signingKeySid, - String signingKeySecret, - String name, - String type, - String environment, - String region, - String mediaRegion, - boolean enableTurn, - boolean enableRecording, - List videoCodecs, - Callback callback) - throws IllegalArgumentException { - if (!environment.equalsIgnoreCase(PROD) - && !environment.equalsIgnoreCase(STAGE) - && !environment.equalsIgnoreCase(DEV)) { - throw new IllegalArgumentException("Invalid Environment!"); - } - if (!type.equalsIgnoreCase(P2P) - && !type.equalsIgnoreCase(GROUP) - && !type.equalsIgnoreCase(GROUP_SMALL)) { - throw new IllegalArgumentException("Invalid Room Type!"); - } - if (!currentEnvironment.equalsIgnoreCase(environment)) { - currentEnvironment = environment; - videoApiService = createVideoApiService(); - } - if (region == null) { - region = "gll"; - } - if (mediaRegion == null) { - mediaRegion = "gll"; - } - String authString = signingKeySid + ":" + signingKeySecret; - String authorization = - "Basic " + Base64.encodeToString(authString.getBytes(), Base64.NO_WRAP); - videoApiService.createRoom( - authorization, - name, - type, - enableTurn, - enableRecording, - videoCodecs, - region, - mediaRegion, - callback); - } - - // Provide a synchronous version of createRoom for tests - public static VideoRoom createRoom( - String accountSid, - String signingKeySid, - String signingKeySecret, - String name, - String type, - String environment, - String region, - String mediaRegion, - boolean enableTurn, - boolean enableRecording, - List videoCodecs) { - if (!environment.equalsIgnoreCase(PROD) - && !environment.equalsIgnoreCase(STAGE) - && !environment.equalsIgnoreCase(DEV)) { - throw new IllegalArgumentException("Invalid Environment!"); - } - if (!type.equalsIgnoreCase(P2P) - && !type.equalsIgnoreCase(GROUP) - && !type.equalsIgnoreCase(GROUP_SMALL)) { - throw new IllegalArgumentException("Invalid Room Type!"); - } - if (!currentEnvironment.equalsIgnoreCase(environment)) { - currentEnvironment = environment; - videoApiService = createVideoApiService(); - } - - if (region == null) { - region = "gll"; - } - if (mediaRegion == null) { - mediaRegion = "gll"; - } - String authString = signingKeySid + ":" + signingKeySecret; - String authorization = - "Basic " + Base64.encodeToString(authString.getBytes(), Base64.NO_WRAP); - - /* - * Occasionally requests to create a room time out on Firebase Test Lab. Retry a reasonable - * amount of times before failing. - */ - int retries = 0; - VideoRoom videoRoom = null; - do { - try { - videoRoom = - videoApiService.createRoom( - authorization, - name, - type, - enableTurn, - enableRecording, - videoCodecs, - region, - mediaRegion); - } catch (RetrofitError createRoomError) { - Log.e( - "VideoApiUtils", - String.format("RetrofitError: %s", createRoomError.getKind().name())); - if (createRoomError.getResponse() != null) { - throw createRoomError; - } - } - - // Wait some time before trying again - if (videoRoom == null) { - try { - Thread.sleep(200); - } catch (InterruptedException e) { - Log.e("VideoApiUtils", e.getMessage()); - } - } - } while (videoRoom == null && retries++ < MAX_RETRIES); - - // Validate the room creation succeeded - if (videoRoom == null) { - throw new IllegalStateException( - String.format( - "Failed to create a Room after %s attempts", - String.valueOf(MAX_RETRIES))); - } - /* - * Validate the room resource. - * - * Note that for a group room the infrastructure will always return enableTurn=true even if - * the request was made with enableTurn=false. - */ - boolean expectedEnableTurn = - type.equalsIgnoreCase(GROUP) || type.equalsIgnoreCase(GROUP_SMALL) || enableTurn; - - boolean isRoomResourceMatchingConfig = - accountSid.equals(videoRoom.getAccountSid()) - && name.equals(videoRoom.getUniqueName()) - && type.equals(videoRoom.getType()) - && expectedEnableTurn == videoRoom.isEnableTurn() - && enableRecording == videoRoom.isRecordParticipantOnConnect(); - if (!isRoomResourceMatchingConfig) { - throw new IllegalStateException( - "Room resource does not match configuration requested for test"); - } - - return videoRoom; - } - - public static VideoRoom completeRoom( - String signingKeySid, String signingKeySecret, String roomSid, String environment) { - if (!environment.equalsIgnoreCase(PROD) - && !environment.equalsIgnoreCase(STAGE) - && !environment.equalsIgnoreCase(DEV)) { - throw new IllegalArgumentException("Invalid Environment!"); - } - if (!currentEnvironment.equalsIgnoreCase(environment)) { - currentEnvironment = environment; - videoApiService = createVideoApiService(); - } - - String authString = signingKeySid + ":" + signingKeySecret; - String authorization = - "Basic " + Base64.encodeToString(authString.getBytes(), Base64.NO_WRAP); - - return videoApiService.modifyRoom(authorization, roomSid, "completed"); - } -} diff --git a/twilioapi/src/main/java/com/twilio/video/twilioapi/model/Links.java b/twilioapi/src/main/java/com/twilio/video/twilioapi/model/Links.java deleted file mode 100644 index eccd97151..000000000 --- a/twilioapi/src/main/java/com/twilio/video/twilioapi/model/Links.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2017 Twilio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twilio.video.twilioapi.model; - -public class Links { - private String recordings; - - public Links() {} -} diff --git a/twilioapi/src/main/java/com/twilio/video/twilioapi/model/TwilioIceServer.java b/twilioapi/src/main/java/com/twilio/video/twilioapi/model/TwilioIceServer.java deleted file mode 100644 index a1c556302..000000000 --- a/twilioapi/src/main/java/com/twilio/video/twilioapi/model/TwilioIceServer.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2017 Twilio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twilio.video.twilioapi.model; - -public class TwilioIceServer { - private String url; - private String username; - private String credential; - - public TwilioIceServer() { - url = ""; - username = ""; - credential = ""; - } - - public String getUrl() { - return url; - } - - public String getUsername() { - return username; - } - - public String getCredential() { - return credential; - } - - public String toString() { - return url; - } -} diff --git a/twilioapi/src/main/java/com/twilio/video/twilioapi/model/TwilioServiceToken.java b/twilioapi/src/main/java/com/twilio/video/twilioapi/model/TwilioServiceToken.java deleted file mode 100644 index 612fd90f0..000000000 --- a/twilioapi/src/main/java/com/twilio/video/twilioapi/model/TwilioServiceToken.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2017 Twilio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twilio.video.twilioapi.model; - -import com.google.gson.annotations.SerializedName; -import java.util.List; - -public class TwilioServiceToken { - - private String username; - - private String password; - - @SerializedName("account_sid") - private String accountSid; - - private String ttl; - - @SerializedName("ice_servers") - private List iceServers; - - @SerializedName("date_created") - private String dateCreated; - - @SerializedName("date_updated") - private String dateUpdated; - - public TwilioServiceToken() {} - - public String getUsername() { - return username; - } - - public String getPassword() { - return password; - } - - public String getAccountSid() { - return accountSid; - } - - public List getIceServers() { - return iceServers; - } - - public String getDateCreated() { - return dateCreated; - } - - public String getDateUpdated() { - return dateUpdated; - } - - public String getTtl() { - return ttl; - } -} diff --git a/twilioapi/src/main/java/com/twilio/video/twilioapi/model/VideoRoom.java b/twilioapi/src/main/java/com/twilio/video/twilioapi/model/VideoRoom.java deleted file mode 100644 index 6eff0ac53..000000000 --- a/twilioapi/src/main/java/com/twilio/video/twilioapi/model/VideoRoom.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2017 Twilio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twilio.video.twilioapi.model; - -import com.google.gson.annotations.SerializedName; - -public class VideoRoom { - private String status; - - @SerializedName("unique_name") - private String uniqueName; - - @SerializedName("date_updated") - private String dateUpdated; - - @SerializedName("max_participants") - private int maxParticipants; - - @SerializedName("record_participants_on_connect") - private boolean recordParticipantOnConnect; - - @SerializedName("enable_turn") - private boolean enableTurn; - - @SerializedName("account_sid") - private String accountSid; - - private String url; - - @SerializedName("end_time") - private String endTime; - - private String sid; - - private String duration; - - @SerializedName("date_created") - private String dateCreated; - - private String type; - - @SerializedName("status_callback_method") - private String statusCallbackMethod; - - @SerializedName("status_callback") - private String statusCallback; - - private Links links; - - public VideoRoom() {} - - public String getStatus() { - return status; - } - - public String getUniqueName() { - return uniqueName; - } - - public String getDateUpdated() { - return dateUpdated; - } - - public int getMaxParticipants() { - return maxParticipants; - } - - public boolean isRecordParticipantOnConnect() { - return recordParticipantOnConnect; - } - - public boolean isEnableTurn() { - return enableTurn; - } - - public String getAccountSid() { - return accountSid; - } - - public String getUrl() { - return url; - } - - public String getEndTime() { - return endTime; - } - - public String getSid() { - return sid; - } - - public String getDuration() { - return duration; - } - - public String getDateCreated() { - return dateCreated; - } - - public String getType() { - return type; - } - - public String getStatusCallbackMethod() { - return statusCallbackMethod; - } - - public String getStatusCallback() { - return statusCallback; - } - - public Links getLinks() { - return links; - } -} diff --git a/twilioapi/src/main/res/values/strings.xml b/twilioapi/src/main/res/values/strings.xml deleted file mode 100644 index 9e41c0abc..000000000 --- a/twilioapi/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - twilioapi -