rn: add ability to disable crash reporting
This commit is contained in:
parent
f646bc7a7a
commit
b3f16926d4
|
@ -1,8 +1,5 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
boolean googleServicesEnabled \
|
||||
= project.file('google-services.json').exists() && !rootProject.ext.libreBuild
|
||||
|
||||
// Crashlytics integration is done as part of Firebase now, so it gets
|
||||
// automagically activated with google-services.json
|
||||
if (googleServicesEnabled) {
|
||||
|
@ -13,7 +10,7 @@ if (googleServicesEnabled) {
|
|||
// This lets us upload a new build at most every 10 seconds for the
|
||||
// next ~680 years.
|
||||
// https://stackoverflow.com/a/38643838
|
||||
def vcode = (int)(((new Date().getTime()/1000) - 1546297200) / 10)
|
||||
def vcode = (int) (((new Date().getTime() / 1000) - 1546297200) / 10)
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
|
@ -143,8 +140,8 @@ gradle.projectsEvaluated {
|
|||
def targetName = variant.name.capitalize()
|
||||
|
||||
def currentRunPackagerTask = tasks.create(
|
||||
name: "run${targetName}ReactPackager",
|
||||
type: Exec) {
|
||||
name: "run${targetName}ReactPackager",
|
||||
type: Exec) {
|
||||
group = "react"
|
||||
description = "Run the React packager."
|
||||
|
||||
|
@ -175,5 +172,5 @@ gradle.projectsEvaluated {
|
|||
}
|
||||
|
||||
if (googleServicesEnabled) {
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.crashlytics.android.Crashlytics;
|
|||
import com.google.firebase.dynamiclinks.FirebaseDynamicLinks;
|
||||
import io.fabric.sdk.android.Fabric;
|
||||
|
||||
import org.jitsi.meet.sdk.JitsiMeet;
|
||||
import org.jitsi.meet.sdk.JitsiMeetActivity;
|
||||
|
||||
/**
|
||||
|
@ -21,7 +22,9 @@ final class GoogleServicesHelper {
|
|||
if (BuildConfig.GOOGLE_SERVICES_ENABLED) {
|
||||
Log.d(activity.getClass().getSimpleName(), "Initializing Google Services");
|
||||
|
||||
Fabric.with(activity, new Crashlytics());
|
||||
if (!JitsiMeet.isCrashReportingDisabled(activity)) {
|
||||
Fabric.with(activity, new Crashlytics());
|
||||
}
|
||||
|
||||
FirebaseDynamicLinks.getInstance().getDynamicLink(activity.getIntent())
|
||||
.addOnSuccessListener(activity, pendingDynamicLinkData -> {
|
||||
|
|
|
@ -161,6 +161,8 @@ ext {
|
|||
|
||||
// Libre build
|
||||
libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
|
||||
|
||||
googleServicesEnabled = project.file('app/google-services.json').exists() && !libreBuild
|
||||
}
|
||||
|
||||
// Force the version of the Android build tools we have chosen on all
|
||||
|
|
|
@ -14,11 +14,13 @@ android {
|
|||
buildTypes {
|
||||
debug {
|
||||
buildConfigField "boolean", "LIBRE_BUILD", "${rootProject.ext.libreBuild}"
|
||||
buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${rootProject.ext.googleServicesEnabled}"
|
||||
}
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
buildConfigField "boolean", "LIBRE_BUILD", "${rootProject.ext.libreBuild}"
|
||||
buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${rootProject.ext.googleServicesEnabled}"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,6 +72,7 @@ dependencies {
|
|||
implementation project(':react-native-calendar-events')
|
||||
implementation project(':react-native-community-async-storage')
|
||||
implementation project(':react-native-community_netinfo')
|
||||
implementation project(':react-native-default-preference')
|
||||
implementation project(':react-native-immersive')
|
||||
implementation project(':react-native-keep-awake')
|
||||
implementation project(':react-native-linear-gradient')
|
||||
|
|
|
@ -76,6 +76,7 @@ class AppInfoModule
|
|||
"version",
|
||||
packageInfo == null ? "" : packageInfo.versionName);
|
||||
constants.put("LIBRE_BUILD", BuildConfig.LIBRE_BUILD);
|
||||
constants.put("GOOGLE_SERVICES_ENABLED", BuildConfig.GOOGLE_SERVICES_ENABLED);
|
||||
|
||||
return constants;
|
||||
}
|
||||
|
|
|
@ -16,11 +16,14 @@
|
|||
*/
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
|
||||
public class JitsiMeet {
|
||||
|
||||
/**
|
||||
* Default {@link JitsiMeetConferenceOptions} which will be used for all conferences. When
|
||||
* joining a conference these options will be merged with the ones passed to
|
||||
|
@ -72,4 +75,10 @@ public class JitsiMeet {
|
|||
reactInstanceManager.showDevOptionsDialog();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isCrashReportingDisabled(Context context) {
|
||||
SharedPreferences preferences = context.getSharedPreferences("jitsi-default-preferences", Context.MODE_PRIVATE);
|
||||
String value = preferences.getString("isCrashReportingDisabled", "");
|
||||
return Boolean.parseBoolean(value);
|
||||
}
|
||||
}
|
|
@ -190,6 +190,7 @@ class ReactInstanceManagerHolder {
|
|||
new com.corbt.keepawake.KCKeepAwakePackage(),
|
||||
new com.facebook.react.shell.MainReactPackage(),
|
||||
new com.horcrux.svg.SvgPackage(),
|
||||
new com.kevinresol.react_native_default_preference.RNDefaultPreferencePackage(),
|
||||
new com.ocetnik.timer.BackgroundTimerPackage(),
|
||||
new com.reactnativecommunity.asyncstorage.AsyncStoragePackage(),
|
||||
new com.reactnativecommunity.netinfo.NetInfoPackage(),
|
||||
|
|
|
@ -9,6 +9,8 @@ include ':react-native-community-async-storage'
|
|||
project(':react-native-community-async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android')
|
||||
include ':react-native-community_netinfo'
|
||||
project(':react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android')
|
||||
include ':react-native-default-preference'
|
||||
project(':react-native-default-preference').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-default-preference/android')
|
||||
include ':react-native-google-signin'
|
||||
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/google-signin/android')
|
||||
include ':react-native-immersive'
|
||||
|
|
|
@ -66,6 +66,7 @@ target 'JitsiMeet' do
|
|||
pod 'RNSound', :path => '../node_modules/react-native-sound'
|
||||
pod 'RNSVG', :path => '../node_modules/react-native-svg'
|
||||
pod 'RNWatch', :path => '../node_modules/react-native-watch-connectivity'
|
||||
pod 'RNDefaultPreference', :path => '../node_modules/react-native-default-preference'
|
||||
|
||||
# Native pod dependencies
|
||||
#
|
||||
|
|
|
@ -353,6 +353,8 @@ PODS:
|
|||
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.1)
|
||||
- RNCAsyncStorage (1.3.4):
|
||||
- React
|
||||
- RNDefaultPreference (1.4.2):
|
||||
- React
|
||||
- RNGoogleSignin (3.0.1):
|
||||
- GoogleSignIn (~> 5.0.0)
|
||||
- React
|
||||
|
@ -409,6 +411,7 @@ DEPENDENCIES:
|
|||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||
- ReactCommon/turbomodule (from `../node_modules/react-native/ReactCommon`)
|
||||
- "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)"
|
||||
- RNDefaultPreference (from `../node_modules/react-native-default-preference`)
|
||||
- "RNGoogleSignin (from `../node_modules/@react-native-community/google-signin`)"
|
||||
- RNSound (from `../node_modules/react-native-sound`)
|
||||
- RNSVG (from `../node_modules/react-native-svg`)
|
||||
|
@ -416,13 +419,11 @@ DEPENDENCIES:
|
|||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
SPEC REPOS:
|
||||
https://github.com/CocoaPods/Specs.git:
|
||||
trunk:
|
||||
- Amplitude-iOS
|
||||
- AppAuth
|
||||
- boost-for-react-native
|
||||
- CocoaLumberjack
|
||||
- ObjectiveDropboxOfficial
|
||||
trunk:
|
||||
- AppAuth
|
||||
- Crashlytics
|
||||
- Fabric
|
||||
- Firebase
|
||||
|
@ -442,6 +443,7 @@ SPEC REPOS:
|
|||
- GTMAppAuth
|
||||
- GTMSessionFetcher
|
||||
- nanopb
|
||||
- ObjectiveDropboxOfficial
|
||||
- PromisesObjC
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
|
@ -509,6 +511,8 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/react-native/ReactCommon"
|
||||
RNCAsyncStorage:
|
||||
:path: "../node_modules/@react-native-community/async-storage"
|
||||
RNDefaultPreference:
|
||||
:path: "../node_modules/react-native-default-preference"
|
||||
RNGoogleSignin:
|
||||
:path: "../node_modules/@react-native-community/google-signin"
|
||||
RNSound:
|
||||
|
@ -578,12 +582,13 @@ SPEC CHECKSUMS:
|
|||
React-RCTVibration: a1bcfcdc0b5a73a1b0829a34cee22bd0e95bacba
|
||||
ReactCommon: 675681aba4fecff5acbc0e440530cc422103c610
|
||||
RNCAsyncStorage: 8e31405a9f12fbf42c2bb330e4560bfd79c18323
|
||||
RNDefaultPreference: 56a405ce61033ac77b95004dccd7ac54c2eb50d1
|
||||
RNGoogleSignin: 39336070b35fc4cea6a98cf111e00480317be0ae
|
||||
RNSound: c980916b596cc15c8dcd2f6ecd3b13c4881dbe20
|
||||
RNSVG: aac12785382e8fd4f28d072fe640612e34914631
|
||||
RNWatch: 09738b339eceb66e4d80a2371633ca5fb380fa42
|
||||
Yoga: 7b4209fda2441f99d54dd6cf4c82b094409bb68f
|
||||
|
||||
PODFILE CHECKSUM: f615794fb9184757b00cd16e534824ba6ee2fc98
|
||||
PODFILE CHECKSUM: 082858daebbe170e7a490de433e7f2a99e0c3701
|
||||
|
||||
COCOAPODS: 1.9.1
|
||||
|
|
|
@ -24,19 +24,10 @@
|
|||
@import Firebase;
|
||||
@import JitsiMeet;
|
||||
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
|
||||
// Initialize Crashlytics and Firebase if a valid GoogleService-Info.plist file was provided.
|
||||
if ([FIRUtilities appContainsRealServiceInfoPlist]) {
|
||||
NSLog(@"Enablign Crashlytics and Firebase");
|
||||
[FIRApp configure];
|
||||
[Fabric with:@[[Crashlytics class]]];
|
||||
}
|
||||
|
||||
JitsiMeet *jitsiMeet = [JitsiMeet sharedInstance];
|
||||
|
||||
jitsiMeet.conferenceActivityType = JitsiMeetConferenceActivityType;
|
||||
|
@ -54,6 +45,13 @@
|
|||
#endif
|
||||
}];
|
||||
|
||||
// Initialize Crashlytics and Firebase if a valid GoogleService-Info.plist file was provided.
|
||||
if ([FIRUtilities appContainsRealServiceInfoPlist] && ![jitsiMeet isCrashReportingDisabled]) {
|
||||
NSLog(@"Enabling Crashlytics and Firebase");
|
||||
[FIRApp configure];
|
||||
[Fabric with:@[[Crashlytics class]]];
|
||||
}
|
||||
|
||||
[jitsiMeet application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
|
||||
return YES;
|
||||
|
|
|
@ -16,12 +16,7 @@
|
|||
|
||||
#import "FIRUtilities.h"
|
||||
|
||||
// Plist file name.
|
||||
NSString *const kGoogleServiceInfoFileName = @"GoogleService-Info";
|
||||
// Plist file type.
|
||||
NSString *const kGoogleServiceInfoFileType = @"plist";
|
||||
NSString *const kGoogleAppIDPlistKey = @"GOOGLE_APP_ID";
|
||||
|
||||
@import JitsiMeet;
|
||||
|
||||
@implementation FIRUtilities
|
||||
|
||||
|
@ -30,37 +25,11 @@ NSString *const kGoogleAppIDPlistKey = @"GOOGLE_APP_ID";
|
|||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
containsRealServiceInfoPlist = [self containsRealServiceInfoPlistInBundle:bundle];
|
||||
containsRealServiceInfoPlist = [InfoPlistUtil containsRealServiceInfoPlistInBundle:bundle];
|
||||
});
|
||||
return containsRealServiceInfoPlist;
|
||||
}
|
||||
|
||||
+ (BOOL)containsRealServiceInfoPlistInBundle:(NSBundle *)bundle {
|
||||
NSString *bundlePath = bundle.bundlePath;
|
||||
if (!bundlePath.length) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString *plistFilePath = [bundle pathForResource:kGoogleServiceInfoFileName
|
||||
ofType:kGoogleServiceInfoFileType];
|
||||
if (!plistFilePath.length) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSDictionary *plist = [NSDictionary dictionaryWithContentsOfFile:plistFilePath];
|
||||
if (!plist) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Perform a very naive validation by checking to see if the plist has the dummy google app id
|
||||
NSString *googleAppID = plist[kGoogleAppIDPlistKey];
|
||||
if (!googleAppID.length) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (NSURL *)extractURL: (FIRDynamicLink*)dynamicLink {
|
||||
NSURL *url = nil;
|
||||
if (dynamicLink != nil) {
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
C69EFA0E209A0F660027712B /* JMCallKitListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = C69EFA0B209A0F660027712B /* JMCallKitListener.swift */; };
|
||||
C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3425E204EF76800E062DD /* DragGestureController.swift */; };
|
||||
C6CC49AF207412CF000DFA42 /* PiPViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */; };
|
||||
C8AFD27F2462C613000293D2 /* InfoPlistUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
C8AFD2802462C613000293D2 /* InfoPlistUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */; };
|
||||
DE438CDA2350934700DD541D /* JavaScriptSandbox.m in Sources */ = {isa = PBXBuildFile; fileRef = DE438CD82350934700DD541D /* JavaScriptSandbox.m */; };
|
||||
DE65AACA2317FFCD00290BEC /* LogUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = DE65AAC92317FFCD00290BEC /* LogUtils.h */; };
|
||||
DE65AACC2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */; };
|
||||
|
@ -105,6 +107,8 @@
|
|||
C6A3425E204EF76800E062DD /* DragGestureController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DragGestureController.swift; sourceTree = "<group>"; };
|
||||
C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PiPViewCoordinator.swift; sourceTree = "<group>"; };
|
||||
C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetView+Private.h"; sourceTree = "<group>"; };
|
||||
C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InfoPlistUtil.h; sourceTree = "<group>"; };
|
||||
C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InfoPlistUtil.m; sourceTree = "<group>"; };
|
||||
DE438CD82350934700DD541D /* JavaScriptSandbox.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JavaScriptSandbox.m; sourceTree = "<group>"; };
|
||||
DE65AAC92317FFCD00290BEC /* LogUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogUtils.h; sourceTree = "<group>"; };
|
||||
DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetBaseLogHandler+Private.h"; sourceTree = "<group>"; };
|
||||
|
@ -223,6 +227,8 @@
|
|||
DEFE535521FB2E8300011A3A /* ReactUtils.m */,
|
||||
0B93EF7C1EC9DDCD0030D24D /* RCTBridgeWrapper.h */,
|
||||
0B93EF7D1EC9DDCD0030D24D /* RCTBridgeWrapper.m */,
|
||||
C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */,
|
||||
C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */,
|
||||
);
|
||||
path = src;
|
||||
sourceTree = "<group>";
|
||||
|
@ -303,6 +309,7 @@
|
|||
DE81A2D42316AC4D00AE1940 /* JitsiMeetLogger.h in Headers */,
|
||||
DE65AACA2317FFCD00290BEC /* LogUtils.h in Headers */,
|
||||
DEAD3226220C497000E93636 /* JitsiMeetConferenceOptions.h in Headers */,
|
||||
C8AFD27F2462C613000293D2 /* InfoPlistUtil.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -482,6 +489,7 @@
|
|||
0B93EF7F1EC9DDCD0030D24D /* RCTBridgeWrapper.m in Sources */,
|
||||
0BA13D311EE83FF8007BEF7F /* ExternalAPI.m in Sources */,
|
||||
0BCA49601EC4B6C600B793EE /* POSIX.m in Sources */,
|
||||
C8AFD2802462C613000293D2 /* InfoPlistUtil.m in Sources */,
|
||||
C6CC49AF207412CF000DFA42 /* PiPViewCoordinator.swift in Sources */,
|
||||
DEFC743F21B178FA00E4DD96 /* LocaleDetector.m in Sources */,
|
||||
0BCA495F1EC4B6C600B793EE /* AudioMode.m in Sources */,
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
#import "InfoPlistUtil.h"
|
||||
|
||||
@interface AppInfo : NSObject<RCTBridgeModule>
|
||||
@end
|
||||
|
||||
|
@ -67,13 +69,15 @@ RCT_EXPORT_MODULE();
|
|||
buildNumber = @"";
|
||||
}
|
||||
|
||||
BOOL isGoogleServiceEnabled = [InfoPlistUtil containsRealServiceInfoPlistInBundle:[NSBundle mainBundle]];
|
||||
|
||||
return @{
|
||||
@"calendarEnabled": [NSNumber numberWithBool:calendarEnabled],
|
||||
@"buildNumber": buildNumber,
|
||||
@"name": name,
|
||||
@"sdkBundlePath": sdkBundlePath,
|
||||
@"version": version
|
||||
@"version": version,
|
||||
@"GOOGLE_SERVICES_ENABLED": [NSNumber numberWithBool:isGoogleServiceEnabled]
|
||||
};
|
||||
};
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright @ 2019-present 8x8, 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface InfoPlistUtil : NSObject
|
||||
|
||||
+ (BOOL)containsRealServiceInfoPlistInBundle:(NSBundle *)bundle;
|
||||
|
||||
@end
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright @ 2019-present 8x8, 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.
|
||||
*/
|
||||
|
||||
#import "InfoPlistUtil.h"
|
||||
|
||||
// Plist file name.
|
||||
NSString *const kGoogleServiceInfoFileName = @"GoogleService-Info";
|
||||
// Plist file type.
|
||||
NSString *const kGoogleServiceInfoFileType = @"plist";
|
||||
NSString *const kGoogleAppIDPlistKey = @"GOOGLE_APP_ID";
|
||||
|
||||
@implementation InfoPlistUtil
|
||||
|
||||
+ (BOOL)containsRealServiceInfoPlistInBundle:(NSBundle *)bundle {
|
||||
NSString *bundlePath = bundle.bundlePath;
|
||||
if (!bundlePath.length) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString *plistFilePath = [bundle pathForResource:kGoogleServiceInfoFileName
|
||||
ofType:kGoogleServiceInfoFileType];
|
||||
if (!plistFilePath.length) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSDictionary *plist = [NSDictionary dictionaryWithContentsOfFile:plistFilePath];
|
||||
if (!plist) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Perform a very naive validation by checking to see if the plist has the dummy google app id
|
||||
NSString *googleAppID = plist[kGoogleAppIDPlistKey];
|
||||
if (!googleAppID.length) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
@end
|
|
@ -20,6 +20,7 @@
|
|||
#import <JitsiMeet/JitsiMeetConferenceOptions.h>
|
||||
#import <JitsiMeet/JitsiMeetLogger.h>
|
||||
#import <JitsiMeet/JitsiMeetBaseLogHandler.h>
|
||||
#import <JitsiMeet/InfoPlistUtil.h>
|
||||
|
||||
|
||||
@interface JitsiMeet : NSObject
|
||||
|
@ -64,4 +65,6 @@
|
|||
|
||||
- (JitsiMeetConferenceOptions *_Nonnull)getInitialConferenceOptions;
|
||||
|
||||
- (BOOL)isCrashReportingDisabled;
|
||||
|
||||
@end
|
||||
|
|
|
@ -132,6 +132,11 @@
|
|||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)isCrashReportingDisabled {
|
||||
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"jitsi-default-preferences"];
|
||||
return [userDefaults stringForKey:@"isCrashReportingDisabled"];
|
||||
}
|
||||
|
||||
- (JitsiMeetConferenceOptions *)optionsFromUserActivity:(NSUserActivity *)userActivity {
|
||||
NSString *activityType = userActivity.activityType;
|
||||
|
||||
|
|
|
@ -582,12 +582,15 @@
|
|||
"settingsView": {
|
||||
"advanced": "Advanced",
|
||||
"alertOk": "OK",
|
||||
"alertCancel": "Cancel",
|
||||
"alertTitle": "Warning",
|
||||
"alertURLText": "The entered server URL is invalid",
|
||||
"buildInfoSection": "Build Information",
|
||||
"conferenceSection": "Conference",
|
||||
"disableCallIntegration": "Disable native call integration",
|
||||
"disableP2P": "Disable Peer-To-Peer mode",
|
||||
"disableCrashReporting": "Disable crash reporting",
|
||||
"disableCrashReportingWarning": "Are you sure you want to disable crash reporting? The setting will be applied after you restart the app.",
|
||||
"displayName": "Display name",
|
||||
"email": "Email",
|
||||
"header": "Settings",
|
||||
|
|
|
@ -14827,6 +14827,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"react-native-default-preference": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-default-preference/-/react-native-default-preference-1.4.2.tgz",
|
||||
"integrity": "sha512-kNhBLv8s6kO2gJJFEKM7qew7oRvJnygjgG1CU2ZEY6SlG5qsRX8z1Ms7z1Oo/XB7fVfyXrAoZDGhIvy+uiByrg=="
|
||||
},
|
||||
"react-native-immersive": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-immersive/-/react-native-immersive-2.0.0.tgz",
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
"react-native-calendar-events": "github:jitsi/react-native-calendar-events#902e6e92d6bae450a6052f76ba4d02f977ffd8f2",
|
||||
"react-native-callstats": "3.61.0",
|
||||
"react-native-collapsible": "1.5.1",
|
||||
"react-native-default-preference": "1.4.2",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-linear-gradient": "2.5.6",
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
import { NativeModules } from 'react-native';
|
||||
|
||||
import DefaultPreference from 'react-native-default-preference';
|
||||
|
||||
export * from './functions.any';
|
||||
|
||||
const { AudioMode } = NativeModules;
|
||||
|
@ -19,3 +21,17 @@ export function handleCallIntegrationChange(disabled: boolean) {
|
|||
AudioMode.setUseConnectionService(!disabled);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles changes to the `disableCrashReporting` setting.
|
||||
* Stores the value into platform specific default preference file, so at app
|
||||
* start-up time it is retrieved on the native side and the crash reporting
|
||||
* is enabled/disabled.
|
||||
*
|
||||
* @param {boolean} disabled - Whether crash reporting is disabled or not.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function handleCrashReportingChange(disabled: boolean) {
|
||||
DefaultPreference.setName('jitsi-default-preferences').then(
|
||||
DefaultPreference.set('isCrashReportingDisabled', disabled.toString()));
|
||||
}
|
||||
|
|
|
@ -41,3 +41,13 @@ export function getCurrentOutputDeviceId(state: Object) {
|
|||
*/
|
||||
export function handleCallIntegrationChange(disabled: boolean) { // eslint-disable-line no-unused-vars
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles changes to the `disableCrashReporting` setting.
|
||||
* Noop on web.
|
||||
*
|
||||
* @param {boolean} disabled - Whether crash reporting is disabled or not.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function handleCrashReportingChange(disabled: boolean) { // eslint-disable-line no-unused-vars
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import { getLocalParticipant, participantUpdated } from '../participants';
|
|||
import { MiddlewareRegistry } from '../redux';
|
||||
|
||||
import { SETTINGS_UPDATED } from './actionTypes';
|
||||
import { handleCallIntegrationChange } from './functions';
|
||||
import { handleCallIntegrationChange, handleCrashReportingChange } from './functions';
|
||||
|
||||
/**
|
||||
* The middleware of the feature base/settings. Distributes changes to the state
|
||||
|
@ -30,6 +30,7 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
_maybeHandleCallIntegrationChange(action);
|
||||
_maybeSetAudioOnly(store, action);
|
||||
_updateLocalParticipant(store, action);
|
||||
_maybeCrashReportingChange(action);
|
||||
break;
|
||||
case SET_LOCATION_URL:
|
||||
_updateLocalParticipantFromUrl(store);
|
||||
|
@ -84,6 +85,19 @@ function _maybeHandleCallIntegrationChange({ settings: { disableCallIntegration
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a change in the `disableCrashReporting` setting.
|
||||
*
|
||||
* @param {Object} action - The redux action.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _maybeCrashReportingChange({ settings: { disableCrashReporting } }) {
|
||||
if (typeof disableCrashReporting === 'boolean') {
|
||||
handleCrashReportingChange(disableCrashReporting);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates {@code startAudioOnly} flag if it's updated in the settings.
|
||||
*
|
||||
|
|
|
@ -24,6 +24,7 @@ const DEFAULT_STATE = {
|
|||
avatarURL: undefined,
|
||||
cameraDeviceId: undefined,
|
||||
disableCallIntegration: undefined,
|
||||
disableCrashReporting: undefined,
|
||||
disableP2P: undefined,
|
||||
displayName: undefined,
|
||||
email: undefined,
|
||||
|
|
|
@ -36,6 +36,11 @@ type State = {
|
|||
*/
|
||||
disableP2P: boolean,
|
||||
|
||||
/**
|
||||
* State variable for the disable crash reporting switch.
|
||||
*/
|
||||
disableCrashReporting: boolean,
|
||||
|
||||
/**
|
||||
* State variable for the display name field.
|
||||
*/
|
||||
|
@ -84,6 +89,7 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
|||
super(props);
|
||||
const {
|
||||
disableCallIntegration,
|
||||
disableCrashReporting,
|
||||
disableP2P,
|
||||
displayName,
|
||||
email,
|
||||
|
@ -94,6 +100,7 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
|||
|
||||
this.state = {
|
||||
disableCallIntegration,
|
||||
disableCrashReporting,
|
||||
disableP2P,
|
||||
displayName,
|
||||
email,
|
||||
|
@ -107,6 +114,7 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
|||
this._onBlurServerURL = this._onBlurServerURL.bind(this);
|
||||
this._onClose = this._onClose.bind(this);
|
||||
this._onDisableCallIntegration = this._onDisableCallIntegration.bind(this);
|
||||
this._onDisableCrashReporting = this._onDisableCrashReporting.bind(this);
|
||||
this._onDisableP2P = this._onDisableP2P.bind(this);
|
||||
this._onShowAdvanced = this._onShowAdvanced.bind(this);
|
||||
this._setURLFieldReference = this._setURLFieldReference.bind(this);
|
||||
|
@ -285,6 +293,24 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
|||
});
|
||||
}
|
||||
|
||||
_onDisableCrashReporting: (boolean) => void;
|
||||
|
||||
/**
|
||||
* Handles the disable crash reporting change event.
|
||||
*
|
||||
* @param {boolean} disableCrashReporting - The new value
|
||||
* option.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onDisableCrashReporting(disableCrashReporting) {
|
||||
if (disableCrashReporting) {
|
||||
this._showCrashReportingDisableAlert();
|
||||
} else {
|
||||
this._disableCrashReporting(disableCrashReporting);
|
||||
}
|
||||
}
|
||||
|
||||
_onClose: () => void;
|
||||
|
||||
/**
|
||||
|
@ -367,7 +393,7 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
|||
* @returns {React$Element}
|
||||
*/
|
||||
_renderAdvancedSettings() {
|
||||
const { disableCallIntegration, disableP2P, showAdvanced } = this.state;
|
||||
const { disableCallIntegration, disableP2P, disableCrashReporting, showAdvanced } = this.state;
|
||||
|
||||
if (!showAdvanced) {
|
||||
return (
|
||||
|
@ -397,6 +423,15 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
|||
onValueChange = { this._onDisableP2P }
|
||||
value = { disableP2P } />
|
||||
</FormRow>
|
||||
{AppInfo.GOOGLE_SERVICES_ENABLED && (
|
||||
<FormRow
|
||||
fieldSeparator = { true }
|
||||
label = 'settingsView.disableCrashReporting'>
|
||||
<Switch
|
||||
onValueChange = { this._onDisableCrashReporting }
|
||||
value = { disableCrashReporting } />
|
||||
</FormRow>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -436,7 +471,41 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows an alert warning the user about disabling crash reporting.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_showCrashReportingDisableAlert() {
|
||||
const { t } = this.props;
|
||||
|
||||
Alert.alert(
|
||||
t('settingsView.alertTitle'),
|
||||
t('settingsView.disableCrashReportingWarning'),
|
||||
[
|
||||
{
|
||||
onPress: () => this._disableCrashReporting(true),
|
||||
text: t('settingsView.alertOk')
|
||||
},
|
||||
{
|
||||
text: t('settingsView.alertCancel')
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
_updateSettings: (Object) => void;
|
||||
|
||||
/**
|
||||
* Updates the settings and sets state for disableCrashReporting.
|
||||
*
|
||||
* @param {boolean} disableCrashReporting - Whether crash reporting is disabled or not.
|
||||
* @returns {void}
|
||||
*/
|
||||
_disableCrashReporting(disableCrashReporting) {
|
||||
this._updateSettings({ disableCrashReporting });
|
||||
this.setState({ disableCrashReporting });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue