Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VBLOCKS-2485: Changes needed due to refactor of react native sdk #129

Merged
merged 13 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -377,10 +377,7 @@ jobs:
- app-install-dependencies
- app-save-google-services-json
- android/install-ndk:
version: "21.4.7075529"
# for aarch64
- android/install-ndk:
version: "24.0.8215888"
version: "25.2.9519653"
- app-android-build

app-detox-android:
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
### Changes
* Refactored and simplified navigators. Now, movement between screens is more
explicit and has finer control.
* Upgraded Twilio Voice SDK to `1.0.0-rc8`.
* Upgraded Twilio Voice SDK to `1.0.0-rc17`.
* Refactored Android implementation to use newly refactored Android Voice React Native SDK

### Fixes
* iOS call timer, no longer shows negative numbers
Expand Down
11 changes: 3 additions & 8 deletions app/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services'

import com.android.build.OutputFile
import org.apache.tools.ant.taskdefs.condition.Os

/**
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
Expand Down Expand Up @@ -262,15 +261,11 @@ android {

dependencies {
androidTestImplementation('com.wix:detox:+')
implementation 'androidx.appcompat:appcompat:1.1.0'


implementation fileTree(dir: "libs", include: ["*.jar"])

//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules

implementation "com.facebook.react:react-native:+"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"

implementation "com.microsoft.appcenter:appcenter-distribute:4.3.1"

debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
Expand Down Expand Up @@ -339,7 +334,7 @@ def getLocalPropertyOrEnv(key) {
return return_value;
}

def stringifyNull(var) {
static def stringifyNull(var) {
if (null == var) {
return "\"null\""
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.twiliovoicereactnativereferenceapp;

import android.Manifest;
import android.os.Build;

import com.wix.detox.Detox;
import com.wix.detox.config.DetoxConfig;

Expand All @@ -10,12 +13,16 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.rule.GrantPermissionRule;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class DetoxTest {
private static final String[] permissionList;
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false);
@Rule
public GrantPermissionRule permissionRule = GrantPermissionRule.grant(permissionList);

@Test
public void runDetoxTests() {
Expand All @@ -26,4 +33,18 @@ public void runDetoxTests() {

Detox.runTests(mActivityRule, detoxConfig);
}

static {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) {
permissionList = new String[] {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.POST_NOTIFICATIONS };
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
permissionList = new String[] {
Manifest.permission.RECORD_AUDIO, Manifest.permission.BLUETOOTH_CONNECT };
} else {
permissionList = new String[] { Manifest.permission.RECORD_AUDIO };
}
}
}
44 changes: 6 additions & 38 deletions app/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.twiliovoicereactnativereferenceapp">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
xmlns:tools="http://schemas.android.com/tools"
package="com.twiliovoicereactnativereferenceapp">

<application
android:name=".MainApplication"
Expand All @@ -13,11 +9,12 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="@style/AppTheme"
android:networkSecurityConfig="@xml/network_security_config">
android:networkSecurityConfig="@xml/network_security_config"
tools:targetApi="n"
tools:ignore="DataExtractionRules">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustPan"
android:exported="true">
Expand All @@ -26,34 +23,5 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Twilio Voice -->
<!-- [START fcm_listener] -->
<service
android:name="com.twiliovoicereactnative.VoiceFirebaseMessagingService"
android:stopWithTask="false"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service
android:enabled="true"
android:name="com.twiliovoicereactnative.IncomingCallNotificationService"
android:foregroundServiceType="microphone"
android:exported="true">
<intent-filter>
<action android:name="ACTION_ACCEPT" />
<action android:name="ACTION_REJECT" />
</intent-filter>
</service>
<activity
android:name="com.twiliovoicereactnative.NotificationProxyActivity"
android:parentActivityName=".MainActivity"
android:noHistory="true"
android:excludeFromRecents="true"
android:taskAffinity=""
android:launchMode="singleTask"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:exported="true" />
</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,58 @@
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.twiliovoicereactnative.VoiceActivityProxy;

import android.Manifest;
import android.content.pm.PackageManager;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.widget.Toast;

public class MainActivity extends ReactActivity {
private static final String TAG = "MainActivity";
private static final int MIC_PERMISSION_REQUEST_CODE = 1;
public static class MainActivityDelegate extends ReactActivityDelegate {
public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
super(activity, mainComponentName);
}

private boolean checkPermissionForMicrophone() {
int resultMic = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);
return resultMic == PackageManager.PERMISSION_GRANTED;
}
@Override
protected ReactRootView createRootView() {
ReactRootView reactRootView = new ReactRootView(getContext());
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
return reactRootView;
}

private void requestPermissionForMicrophone() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
Log.d(TAG, "Microphone permissions needed. Please allow in your application settings.");
} else {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.RECORD_AUDIO},
MIC_PERMISSION_REQUEST_CODE);
@Override
protected boolean isConcurrentRootEnabled() {
// If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
// More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
}

private final VoiceActivityProxy activityProxy = new VoiceActivityProxy(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarifying Question: Will users who just use the SDK also need to make these changes in their React Native Apps?
I.E: users not using the reference app, but using the sdk

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but we are still in beta, and it will make customers lives easier down the line... because we abstract much of it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like these changes will be included in beta.4, could we have a guide to updating to beta.4 for users who are on beta.3 and below?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this,
permission -> {
if (Manifest.permission.RECORD_AUDIO.equals(permission)) {
Toast.makeText(
MainActivity.this,
"Microphone permissions needed. Please allow in your application settings.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Android doesn't automatically give these prompts?

Copy link
Contributor Author

@afalls-twilio afalls-twilio Dec 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, it only places a system pop-up when you request permissions.... but they can always disable it later from the system menus.

Toast.LENGTH_LONG).show();
} else if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) &&
Manifest.permission.BLUETOOTH_CONNECT.equals(permission)) {
Toast.makeText(
MainActivity.this,
"Bluetooth permissions needed. Please allow in your application settings.",
Toast.LENGTH_LONG).show();
} else if ((Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) &&
Manifest.permission.POST_NOTIFICATIONS.equals(permission)) {
Toast.makeText(
MainActivity.this,
"Notification permissions needed. Please allow in your application settings.",
Toast.LENGTH_LONG).show();
}
});
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
Expand All @@ -56,30 +77,18 @@ protected ReactActivityDelegate createReactActivityDelegate() {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (!checkPermissionForMicrophone()) {
requestPermissionForMicrophone();
}
activityProxy.onCreate(savedInstanceState);
}

public static class MainActivityDelegate extends ReactActivityDelegate {
public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
super(activity, mainComponentName);
}

@Override
protected ReactRootView createRootView() {
ReactRootView reactRootView = new ReactRootView(getContext());
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
return reactRootView;
}
@Override
public void onDestroy() {
activityProxy.onDestroy();
super.onDestroy();
}

@Override
protected boolean isConcurrentRootEnabled() {
// If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
// More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
activityProxy.onNewIntent(intent);
}
}
Loading