airbridge-react-native-sdk-restricted 2.8.7 → 2.8.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/.github/actions/add-github-check/action.yml +78 -0
  2. package/.github/actions/add-github-comment/action.yml +48 -0
  3. package/.github/actions/add-slack-message/action.yml +32 -0
  4. package/.github/actions/edit-github-check/action.yml +59 -0
  5. package/.github/actions/edit-github-comment/action.yml +41 -0
  6. package/.github/pull_request_template.md +5 -0
  7. package/.github/readme.md +53 -0
  8. package/.github/workflows/build.yml +367 -0
  9. package/.github/workflows/gitflow.yml +20 -0
  10. package/.github/workflows/release-restricted.yml +35 -0
  11. package/.github/workflows/release.yml +32 -0
  12. package/android/.settings/org.eclipse.buildship.core.prefs +2 -0
  13. package/android/src/main/java/co/ab180/airbridge/reactnative/AirbridgeRN.java +19 -4
  14. package/android/src/main/java/co/ab180/airbridge/reactnative/ConfigReader.java +63 -40
  15. package/changelog.md +10 -0
  16. package/ios/AirbridgeRN/ARNConfigReader.h +1 -1
  17. package/ios/AirbridgeRN/ARNConfigReader.m +31 -30
  18. package/ios/AirbridgeRN/AirbridgeRN.m +26 -2
  19. package/ios/copy-config.rb +1 -1
  20. package/package.json +1 -1
  21. package/qa/.bundle/config +2 -0
  22. package/qa/.eslintrc.js +4 -0
  23. package/qa/.prettierrc.js +7 -0
  24. package/qa/.watchmanconfig +1 -0
  25. package/qa/Gemfile +9 -0
  26. package/qa/Gemfile.lock +105 -0
  27. package/qa/__tests__/App.test.tsx +17 -0
  28. package/qa/airbridge.json +7 -0
  29. package/qa/android/app/build.gradle +130 -0
  30. package/qa/android/app/debug.keystore +0 -0
  31. package/qa/android/app/google-services.json +29 -0
  32. package/qa/android/app/proguard-rules.pro +10 -0
  33. package/qa/android/app/src/debug/AndroidManifest.xml +9 -0
  34. package/qa/android/app/src/main/AndroidManifest.xml +65 -0
  35. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/ConfigurationLoader.kt +49 -0
  36. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/MainActivity.kt +35 -0
  37. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/MainApplication.kt +46 -0
  38. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/module/DeviceInfoInteractor.kt +60 -0
  39. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/module/DeviceInfoUtils.kt +115 -0
  40. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/module/IdentifiersInteractor.kt +83 -0
  41. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/module/InstallReferrerInteractor.kt +91 -0
  42. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/module/ModuleInjector.kt +22 -0
  43. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/module/PermissionInteractor.kt +55 -0
  44. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/module/UserInfoInteractor.kt +74 -0
  45. package/qa/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
  46. package/qa/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  47. package/qa/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  48. package/qa/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  49. package/qa/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  50. package/qa/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  51. package/qa/android/app/src/main/res/values/strings.xml +3 -0
  52. package/qa/android/app/src/main/res/values/styles.xml +9 -0
  53. package/qa/android/build.gradle +28 -0
  54. package/qa/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  55. package/qa/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  56. package/qa/android/gradle.properties +41 -0
  57. package/qa/android/gradlew +249 -0
  58. package/qa/android/gradlew.bat +92 -0
  59. package/qa/android/settings.gradle +4 -0
  60. package/qa/app.json +4 -0
  61. package/qa/babel.config.js +3 -0
  62. package/qa/index.js +5 -0
  63. package/qa/ios/.xcode.env +11 -0
  64. package/qa/ios/AirbridgeQA/AirbridgeQA.entitlements +17 -0
  65. package/qa/ios/AirbridgeQA/AppDelegate.h +6 -0
  66. package/qa/ios/AirbridgeQA/AppDelegate.mm +123 -0
  67. package/qa/ios/AirbridgeQA/DeviceInfoInteractor.m +14 -0
  68. package/qa/ios/AirbridgeQA/DeviceInfoInteractor.swift +151 -0
  69. package/qa/ios/AirbridgeQA/IdentifiersInteractor.m +14 -0
  70. package/qa/ios/AirbridgeQA/IdentifiersInteractor.swift +40 -0
  71. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
  72. package/qa/ios/AirbridgeQA/Images.xcassets/Contents.json +6 -0
  73. package/qa/ios/AirbridgeQA/Info.plist +66 -0
  74. package/qa/ios/AirbridgeQA/LaunchScreen.storyboard +47 -0
  75. package/qa/ios/AirbridgeQA/PermissionInteractor.m +14 -0
  76. package/qa/ios/AirbridgeQA/PermissionInteractor.swift +19 -0
  77. package/qa/ios/AirbridgeQA/PrivacyInfo.xcprivacy +39 -0
  78. package/qa/ios/AirbridgeQA/UserInfoInteractor.m +57 -0
  79. package/qa/ios/AirbridgeQA/UserInfoInteractor.swift +49 -0
  80. package/qa/ios/AirbridgeQA/main.m +10 -0
  81. package/qa/ios/AirbridgeQA.xcodeproj/project.pbxproj +790 -0
  82. package/qa/ios/AirbridgeQA.xcodeproj/xcshareddata/xcschemes/AirbridgeQA.xcscheme +88 -0
  83. package/qa/ios/AirbridgeQA.xcworkspace/contents.xcworkspacedata +10 -0
  84. package/qa/ios/AirbridgeQA.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  85. package/qa/ios/AirbridgeQATests/AirbridgeQATests.m +66 -0
  86. package/qa/ios/AirbridgeQATests/Info.plist +24 -0
  87. package/qa/ios/GoogleService-Info.plist +30 -0
  88. package/qa/ios/Library/airbridge-ios-sdk-qa-library.podspec +26 -0
  89. package/qa/ios/Podfile +44 -0
  90. package/qa/ios/Podfile.lock +1634 -0
  91. package/qa/jest.config.js +3 -0
  92. package/qa/metro.config.js +67 -0
  93. package/qa/package-lock.json +14289 -0
  94. package/qa/package.json +47 -0
  95. package/qa/resource/arrow_back.png +0 -0
  96. package/qa/resource/home.png +0 -0
  97. package/qa/resource/info.png +0 -0
  98. package/qa/resource/link.png +0 -0
  99. package/qa/resource/refresh.png +0 -0
  100. package/qa/resource/token.png +0 -0
  101. package/qa/source/App.js +58 -0
  102. package/qa/source/common/Colors.js +20 -0
  103. package/qa/source/common/FCMService.js +94 -0
  104. package/qa/source/common/Native.ts +39 -0
  105. package/qa/source/common/Storage.js +13 -0
  106. package/qa/source/common/Styles.js +39 -0
  107. package/qa/source/component/AttributeEntryInputDialog.js +117 -0
  108. package/qa/source/component/AttributeTypeInputDialog.js +100 -0
  109. package/qa/source/component/ConfirmDialog.js +72 -0
  110. package/qa/source/component/CustomButton.js +50 -0
  111. package/qa/source/component/CustomEventParamsDialog.js +150 -0
  112. package/qa/source/component/CustomTextInput.js +40 -0
  113. package/qa/source/component/EntryInputDialog.js +89 -0
  114. package/qa/source/component/HorizontalPreference.js +46 -0
  115. package/qa/source/component/ImageButton.js +35 -0
  116. package/qa/source/component/InjectInputDialog.js +80 -0
  117. package/qa/source/component/MessageDialog.js +81 -0
  118. package/qa/source/component/UrlInputDialog.js +80 -0
  119. package/qa/source/component/ValueInputDialog.js +80 -0
  120. package/qa/source/component/VerticalPreference.js +42 -0
  121. package/qa/source/navigations/Stack.js +110 -0
  122. package/qa/source/pages/Browse.js +118 -0
  123. package/qa/source/pages/DeviceInfo.js +135 -0
  124. package/qa/source/pages/Event.js +171 -0
  125. package/qa/source/pages/Home.js +136 -0
  126. package/qa/source/pages/Identifiers.js +108 -0
  127. package/qa/source/pages/InstallReferrer.js +64 -0
  128. package/qa/source/pages/Placement.js +38 -0
  129. package/qa/source/pages/RequestPermissions.tsx +41 -0
  130. package/qa/source/pages/UserInfo.js +168 -0
  131. package/qa/source/pages/appInfo.js +22 -0
  132. package/qa/tsconfig.json +3 -0
  133. package/scripts/addiOSFramework.js +48 -0
  134. package/scripts/build-qa.sh +64 -0
  135. package/scripts/change_restricted.sh +21 -0
  136. package/scripts/update_native_version.sh +104 -0
  137. package/source/module/Attribution.ts +60 -0
  138. package/src/State.js +10 -2
  139. package/src/WebInterface.js +1 -1
@@ -0,0 +1,130 @@
1
+ apply plugin: "com.android.application"
2
+ apply plugin: "com.google.gms.google-services"
3
+ apply plugin: "org.jetbrains.kotlin.android"
4
+ apply plugin: "com.facebook.react"
5
+
6
+ /**
7
+ * This is the configuration block to customize your React Native Android app.
8
+ * By default you don't need to apply any configuration, just uncomment the lines you need.
9
+ */
10
+ react {
11
+ /* Folders */
12
+ // The root of your project, i.e. where "package.json" lives. Default is '..'
13
+ // root = file("../")
14
+ // The folder where the react-native NPM package is. Default is ../node_modules/react-native
15
+ // reactNativeDir = file("../node_modules/react-native")
16
+ // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
17
+ // codegenDir = file("../node_modules/@react-native/codegen")
18
+ // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
19
+ // cliFile = file("../node_modules/react-native/cli.js")
20
+
21
+ /* Variants */
22
+ // The list of variants to that are debuggable. For those we're going to
23
+ // skip the bundling of the JS bundle and the assets. By default is just 'debug'.
24
+ // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
25
+ // debuggableVariants = ["liteDebug", "prodDebug"]
26
+
27
+ /* Bundling */
28
+ // A list containing the node command and its flags. Default is just 'node'.
29
+ // nodeExecutableAndArgs = ["node"]
30
+ //
31
+ // The command to run when bundling. By default is 'bundle'
32
+ // bundleCommand = "ram-bundle"
33
+ //
34
+ // The path to the CLI configuration file. Default is empty.
35
+ // bundleConfig = file(../rn-cli.config.js)
36
+ //
37
+ // The name of the generated asset file containing your JS bundle
38
+ // bundleAssetName = "MyApplication.android.bundle"
39
+ //
40
+ // The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
41
+ // entryFile = file("../js/MyApplication.android.js")
42
+ //
43
+ // A list of extra flags to pass to the 'bundle' commands.
44
+ // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
45
+ // extraPackagerArgs = []
46
+
47
+ /* Hermes Commands */
48
+ // The hermes compiler command to run. By default it is 'hermesc'
49
+ // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
50
+ //
51
+ // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
52
+ // hermesFlags = ["-O", "-output-source-map"]
53
+ }
54
+
55
+ /**
56
+ * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
57
+ */
58
+ def enableProguardInReleaseBuilds = false
59
+
60
+ /**
61
+ * The preferred build flavor of JavaScriptCore (JSC)
62
+ *
63
+ * For example, to use the international variant, you can use:
64
+ * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
65
+ *
66
+ * The international variant includes ICU i18n library and necessary data
67
+ * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
68
+ * give correct results when using with locales other than en-US. Note that
69
+ * this variant is about 6MiB larger per architecture than default.
70
+ */
71
+ def jscFlavor = 'org.webkit:android-jsc:+'
72
+
73
+ android {
74
+ ndkVersion rootProject.ext.ndkVersion
75
+ buildToolsVersion rootProject.ext.buildToolsVersion
76
+ compileSdk rootProject.ext.compileSdkVersion
77
+
78
+ namespace "co.ab180.airbridge.qa.application"
79
+ defaultConfig {
80
+ applicationId "co.ab180.airbridge.qa.application"
81
+ minSdkVersion rootProject.ext.minSdkVersion
82
+ targetSdkVersion rootProject.ext.targetSdkVersion
83
+ versionCode 1
84
+ versionName "1.0"
85
+ }
86
+ signingConfigs {
87
+ debug {
88
+ storeFile file('debug.keystore')
89
+ storePassword 'android'
90
+ keyAlias 'androiddebugkey'
91
+ keyPassword 'android'
92
+ }
93
+ if (System.getenv("KEYSTORE_FILE") != null) {
94
+ release {
95
+ storeFile file(System.getenv("KEYSTORE_FILE"))
96
+ storePassword System.getenv("KEYSTORE_PASSWORD")
97
+ keyAlias System.getenv("KEYSTORE_ALIAS")
98
+ keyPassword System.getenv("KEYSTORE_ALIAS_PASSWORD")
99
+ }
100
+ }
101
+ }
102
+ buildTypes {
103
+ debug {
104
+ signingConfig signingConfigs.debug
105
+ }
106
+ if (System.getenv("KEYSTORE_FILE") != null) {
107
+ release {
108
+ signingConfig signingConfigs.release
109
+ minifyEnabled enableProguardInReleaseBuilds
110
+ proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
111
+ }
112
+ }
113
+ }
114
+ }
115
+
116
+ dependencies {
117
+
118
+ // The version of react-native is set by the React Native Gradle Plugin
119
+ implementation("com.facebook.react:react-android")
120
+
121
+ if (hermesEnabled.toBoolean()) {
122
+ implementation("com.facebook.react:hermes-android")
123
+ } else {
124
+ implementation jscFlavor
125
+ }
126
+
127
+ implementation("io.airbridge:configuration-spec:1.0")
128
+ }
129
+
130
+ apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
Binary file
@@ -0,0 +1,29 @@
1
+ {
2
+ "project_info": {
3
+ "project_number": "727373731449",
4
+ "project_id": "qa-automation-6cee5",
5
+ "storage_bucket": "qa-automation-6cee5.appspot.com"
6
+ },
7
+ "client": [
8
+ {
9
+ "client_info": {
10
+ "mobilesdk_app_id": "1:727373731449:android:17d30d3e072ce63b0f66a8",
11
+ "android_client_info": {
12
+ "package_name": "co.ab180.airbridge.qa.application"
13
+ }
14
+ },
15
+ "oauth_client": [],
16
+ "api_key": [
17
+ {
18
+ "current_key": "AIzaSyDJmjN-mFc1PEHAyd8YlYGf-JBLmqU0sKg"
19
+ }
20
+ ],
21
+ "services": {
22
+ "appinvite_service": {
23
+ "other_platform_oauth_client": []
24
+ }
25
+ }
26
+ }
27
+ ],
28
+ "configuration_version": "1"
29
+ }
@@ -0,0 +1,10 @@
1
+ # Add project specific ProGuard rules here.
2
+ # By default, the flags in this file are appended to flags specified
3
+ # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4
+ # You can edit the include path and order by changing the proguardFiles
5
+ # directive in build.gradle.
6
+ #
7
+ # For more details, see
8
+ # http://developer.android.com/guide/developing/tools/proguard.html
9
+
10
+ # Add any project specific keep options here:
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ xmlns:tools="http://schemas.android.com/tools">
4
+
5
+ <application
6
+ android:usesCleartextTraffic="true"
7
+ tools:targetApi="28"
8
+ tools:ignore="GoogleAppIndexingWarning"/>
9
+ </manifest>
@@ -0,0 +1,65 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <uses-permission android:name="android.permission.INTERNET" />
3
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
4
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
5
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
6
+ <uses-permission android:name="android.permission.BLUETOOTH" />
7
+
8
+ <queries>
9
+ <!-- Google Play Store -->
10
+ <package android:name="com.android.vending" />
11
+ <package android:name="com.google.android.gms" />
12
+ <!-- Huawei App Market -->
13
+ <package android:name="com.huawei.hwid" />
14
+ <package android:name="com.huawei.appmarket" />
15
+ </queries>
16
+
17
+ <application
18
+ android:name=".MainApplication"
19
+ android:allowBackup="false"
20
+ android:icon="@mipmap/ic_launcher"
21
+ android:label="@string/app_name"
22
+ android:roundIcon="@mipmap/ic_launcher"
23
+ android:theme="@style/AppTheme">
24
+ <activity
25
+ android:name=".MainActivity"
26
+ android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
27
+ android:exported="true"
28
+ android:label="@string/app_name"
29
+ android:launchMode="singleTask"
30
+ android:windowSoftInputMode="adjustResize">
31
+ <intent-filter>
32
+ <action android:name="android.intent.action.MAIN" />
33
+ <category android:name="android.intent.category.LAUNCHER" />
34
+ </intent-filter>
35
+
36
+ <intent-filter android:autoVerify="true">
37
+ <action android:name="android.intent.action.VIEW" />
38
+
39
+ <category android:name="android.intent.category.DEFAULT" />
40
+ <category android:name="android.intent.category.BROWSABLE" />
41
+
42
+ <data android:scheme="http" android:host="qaabr.abr.ge" />
43
+ <data android:scheme="https" android:host="qaabr.abr.ge" />
44
+ </intent-filter>
45
+ <intent-filter android:autoVerify="true">
46
+ <action android:name="android.intent.action.VIEW" />
47
+
48
+ <category android:name="android.intent.category.DEFAULT" />
49
+ <category android:name="android.intent.category.BROWSABLE" />
50
+
51
+ <data android:scheme="http" android:host="qaabr.airbridge.io" />
52
+ <data android:scheme="https" android:host="qaabr.airbridge.io" />
53
+ </intent-filter>
54
+ <intent-filter>
55
+ <action android:name="android.intent.action.VIEW" />
56
+
57
+ <category android:name="android.intent.category.DEFAULT" />
58
+ <category android:name="android.intent.category.BROWSABLE" />
59
+
60
+ <data android:scheme="qaabr" />
61
+ </intent-filter>
62
+ </activity>
63
+ </application>
64
+
65
+ </manifest>
@@ -0,0 +1,49 @@
1
+ package co.ab180.airbridge.qa.application
2
+
3
+ import android.app.Application
4
+ import android.content.Context
5
+ import android.util.Log
6
+ import co.ab180.airbridge.reactnative.AirbridgeRN
7
+ import co.ab180.configuration.Loader
8
+ import java.lang.reflect.Method
9
+
10
+ class ConfigurationLoader {
11
+
12
+ companion object {
13
+ val TAG = "Airbridge"
14
+ }
15
+
16
+ fun init(application: Application) {
17
+ findInitMethod()?.run {
18
+ invoke(
19
+ null,
20
+ application,
21
+ "qaabr",
22
+ "fe67302f822445d98591566d5fae1293",
23
+ loadOption(application)
24
+ )
25
+ }
26
+ }
27
+
28
+ private fun findInitMethod(): Method? =
29
+ try {
30
+ AirbridgeRN::class.java.getDeclaredMethod(
31
+ "init",
32
+ Application::class.java,
33
+ String::class.java,
34
+ String::class.java,
35
+ Map::class.java
36
+ )
37
+ } catch (throwable: Throwable) {
38
+ Log.d(TAG, "find init method error : $throwable")
39
+ null
40
+ }?.also {
41
+ it.isAccessible = true
42
+ Log.d(TAG, "find init method : $it")
43
+ }
44
+
45
+ private fun loadOption(context: Context): Map<String, Any> =
46
+ Loader.loadOption(context)
47
+ .let { Loader.convertAirbridgeJsonFormat(it) }
48
+ .also { Log.d(TAG, "loadOption : $it") }
49
+ }
@@ -0,0 +1,35 @@
1
+ package co.ab180.airbridge.qa.application
2
+
3
+ import android.content.Intent
4
+ import co.ab180.airbridge.reactnative.AirbridgeRN
5
+ import com.facebook.react.ReactActivity
6
+ import com.facebook.react.ReactActivityDelegate
7
+ import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
8
+ import com.facebook.react.defaults.DefaultReactActivityDelegate
9
+
10
+ class MainActivity : ReactActivity() {
11
+
12
+ /**
13
+ * Returns the name of the main component registered from JavaScript. This is used to schedule
14
+ * rendering of the component.
15
+ */
16
+ override fun getMainComponentName(): String = "AirbridgeQA"
17
+
18
+ /**
19
+ * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
20
+ * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
21
+ */
22
+ override fun createReactActivityDelegate(): ReactActivityDelegate =
23
+ DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
24
+
25
+ override fun onResume() {
26
+ super.onResume()
27
+
28
+ AirbridgeRN.processDeeplinkData(intent)
29
+ }
30
+
31
+ override fun onNewIntent(intent: Intent?) {
32
+ super.onNewIntent(intent)
33
+ setIntent(intent)
34
+ }
35
+ }
@@ -0,0 +1,46 @@
1
+ package co.ab180.airbridge.qa.application
2
+
3
+ import android.app.Application
4
+ import co.ab180.airbridge.qa.application.module.ModuleInjector
5
+ import com.facebook.react.PackageList
6
+ import com.facebook.react.ReactApplication
7
+ import com.facebook.react.ReactHost
8
+ import com.facebook.react.ReactNativeHost
9
+ import com.facebook.react.ReactPackage
10
+ import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
11
+ import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
12
+ import com.facebook.react.defaults.DefaultReactNativeHost
13
+ import com.facebook.soloader.SoLoader
14
+
15
+ class MainApplication : Application(), ReactApplication {
16
+
17
+ override val reactNativeHost: ReactNativeHost =
18
+ object : DefaultReactNativeHost(this) {
19
+ override fun getPackages(): List<ReactPackage> =
20
+ PackageList(this).packages.apply {
21
+ // Packages that cannot be autolinked yet can be added manually here, for example:
22
+ add(ModuleInjector())
23
+ }
24
+
25
+ override fun getJSMainModuleName(): String = "index"
26
+
27
+ override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
28
+
29
+ override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
30
+ override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
31
+ }
32
+
33
+ override val reactHost: ReactHost
34
+ get() = getDefaultReactHost(applicationContext, reactNativeHost)
35
+
36
+ override fun onCreate() {
37
+ super.onCreate()
38
+ SoLoader.init(this, false)
39
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
40
+ // If you opted-in for the New Architecture, we load the native entry point for this app.
41
+ load()
42
+ }
43
+
44
+ ConfigurationLoader().init(this)
45
+ }
46
+ }
@@ -0,0 +1,60 @@
1
+ package co.ab180.airbridge.qa.application.module
2
+
3
+ import android.bluetooth.BluetoothAdapter
4
+ import android.content.Context
5
+ import android.os.Build
6
+ import android.telephony.TelephonyManager
7
+ import com.facebook.react.bridge.Promise
8
+ import com.facebook.react.bridge.ReactApplicationContext
9
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
10
+ import com.facebook.react.bridge.ReactMethod
11
+ import org.json.JSONObject
12
+ import java.util.Locale
13
+ import java.util.TimeZone
14
+
15
+ class DeviceInfoInteractor(
16
+ reactContext: ReactApplicationContext?
17
+ ) : ReactContextBaseJavaModule(reactContext) {
18
+
19
+ override fun getName(): String = "DeviceInfoInteractor"
20
+
21
+ @ReactMethod
22
+ fun deviceInfo(promise: Promise) {
23
+ promise.resolve(
24
+ JSONObject().apply {
25
+ put("responseCode", 200)
26
+ put("data", request(reactApplicationContext))
27
+ }.toString()
28
+ )
29
+ }
30
+
31
+ private fun request(context: Context): JSONObject =
32
+ JSONObject().apply {
33
+ put("deviceModel", Build.MODEL)
34
+ put("deviceManufacturer", Build.MANUFACTURER)
35
+ put("osVersion", Build.VERSION.RELEASE)
36
+ put("locale", "${Locale.getDefault().language}-${Locale.getDefault().country}")
37
+ put("timezone", TimeZone.getDefault().id)
38
+
39
+ getScreenInfo(context).let {
40
+ put("orientation", it.orientation)
41
+ put("screenSize", "${it.width}x${it.height} ${it.density}DPI")
42
+ }
43
+ getLastKnownLocation(context)?.let {
44
+ put("location", "${it.longitude}, ${it.latitude}, ${it.altitude}")
45
+ put("speed", it.speed)
46
+ }
47
+
48
+ val telephonyManager =
49
+ context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
50
+ put("networkCarrier", telephonyManager.simOperatorName)
51
+
52
+ put("bluetoothStatus", BluetoothAdapter.getDefaultAdapter().isEnabled.toString())
53
+
54
+ getNetworkStatus(context)?.let {
55
+ put("cellularStatus", it.cellular.toString())
56
+ put("wifiStatus", it.wifi.toString())
57
+ }
58
+ }
59
+ }
60
+
@@ -0,0 +1,115 @@
1
+ package co.ab180.airbridge.qa.application.module
2
+
3
+ import android.Manifest
4
+ import android.annotation.SuppressLint
5
+ import android.content.Context
6
+ import android.content.pm.PackageManager
7
+ import android.content.res.Configuration
8
+ import android.location.Location
9
+ import android.location.LocationManager
10
+ import android.net.ConnectivityManager
11
+ import android.net.NetworkCapabilities
12
+ import android.os.Build
13
+ import android.util.DisplayMetrics
14
+ import android.view.WindowManager
15
+ import androidx.core.app.ActivityCompat
16
+
17
+ @Suppress("DEPRECATION")
18
+ internal fun getScreenInfo(context: Context): ScreenInfo {
19
+ val orientation =
20
+ if (context.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
21
+ "portrait"
22
+ } else {
23
+ "landscape"
24
+ }
25
+ val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
26
+ val realDisplayMetrics = DisplayMetrics()
27
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
28
+ windowManager.defaultDisplay.getRealMetrics(realDisplayMetrics)
29
+ }
30
+ return ScreenInfo(
31
+ orientation = orientation,
32
+ width = realDisplayMetrics.widthPixels,
33
+ height = realDisplayMetrics.heightPixels,
34
+ density = realDisplayMetrics.densityDpi,
35
+ )
36
+ }
37
+
38
+ internal fun Context.isPermissionGranted(permission: String): Boolean =
39
+ ActivityCompat.checkSelfPermission(this, permission) ==
40
+ PackageManager.PERMISSION_GRANTED
41
+
42
+ @SuppressLint("MissingPermission")
43
+ @Suppress("DEPRECATION")
44
+ internal fun getLastKnownLocation(context: Context): LocationInfo? {
45
+ val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
46
+
47
+ if (context.isPermissionGranted(Manifest.permission.ACCESS_COARSE_LOCATION) ||
48
+ context.isPermissionGranted(Manifest.permission.ACCESS_FINE_LOCATION)
49
+ ) {
50
+ val gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
51
+ val netLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
52
+ val bestLocation: Location = when {
53
+ (gpsLocation != null) and (netLocation != null) ->
54
+ if (gpsLocation!!.accuracy < netLocation!!.accuracy) {
55
+ gpsLocation
56
+ } else {
57
+ netLocation
58
+ }
59
+ (gpsLocation != null) -> gpsLocation
60
+ else -> netLocation
61
+ } ?: return null
62
+ return LocationInfo(
63
+ longitude = bestLocation.longitude,
64
+ latitude = bestLocation.latitude,
65
+ altitude = bestLocation.altitude,
66
+ speed = bestLocation.speed
67
+ )
68
+ } else {
69
+ return null
70
+ }
71
+ }
72
+
73
+ @Suppress("DEPRECATION")
74
+ internal fun getNetworkStatus(context: Context): NetworkStatus? {
75
+ val connectivityManager =
76
+ context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
77
+
78
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
79
+ val activeNetwork = connectivityManager.activeNetwork
80
+ val capabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
81
+ capabilities?.let {
82
+ NetworkStatus(
83
+ cellular = it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR),
84
+ wifi = it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
85
+ )
86
+ }
87
+ } else {
88
+ val networkInfo = connectivityManager.activeNetworkInfo
89
+ networkInfo?.type?.let {
90
+ NetworkStatus(
91
+ cellular = (it == ConnectivityManager.TYPE_MOBILE),
92
+ wifi = (it == ConnectivityManager.TYPE_WIFI)
93
+ )
94
+ }
95
+ }
96
+ }
97
+
98
+ internal data class ScreenInfo(
99
+ val orientation: String,
100
+ val width: Int,
101
+ val height: Int,
102
+ val density: Int,
103
+ )
104
+
105
+ internal data class LocationInfo(
106
+ val longitude: Double,
107
+ val latitude: Double,
108
+ val altitude: Double,
109
+ val speed: Float
110
+ )
111
+
112
+ internal data class NetworkStatus(
113
+ val cellular: Boolean,
114
+ val wifi: Boolean
115
+ )
@@ -0,0 +1,83 @@
1
+ package co.ab180.airbridge.qa.application.module
2
+
3
+ import co.ab180.airbridge.AdvertisingIdInfo
4
+ import co.ab180.airbridge.Airbridge
5
+ import co.ab180.airbridge.AirbridgeCallback
6
+ import com.facebook.react.bridge.Promise
7
+ import com.facebook.react.bridge.ReactApplicationContext
8
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
9
+ import com.facebook.react.bridge.ReactMethod
10
+ import kotlinx.coroutines.GlobalScope
11
+ import kotlinx.coroutines.channels.awaitClose
12
+ import kotlinx.coroutines.flow.Flow
13
+ import kotlinx.coroutines.flow.callbackFlow
14
+ import kotlinx.coroutines.flow.combine
15
+ import kotlinx.coroutines.flow.flow
16
+ import kotlinx.coroutines.launch
17
+ import org.json.JSONObject
18
+
19
+ class IdentifiersInteractor(
20
+ reactContext: ReactApplicationContext?
21
+ ) : ReactContextBaseJavaModule(reactContext) {
22
+
23
+ override fun getName(): String = "IdentifiersInteractor"
24
+
25
+ @ReactMethod
26
+ fun identifiers(promise: Promise) {
27
+ request {
28
+ promise.resolve(
29
+ JSONObject().apply {
30
+ put("responseCode", 200)
31
+ put("data", it)
32
+ }.toString()
33
+ )
34
+ }
35
+ }
36
+
37
+ private fun request(callback : (JSONObject) -> Unit){
38
+ GlobalScope.launch {
39
+ combine(
40
+ requestAppSetID(),
41
+ requestGeneratedDeviceUUID(),
42
+ requestGAID()
43
+ ) { appSetID, generatedDeviceUUID, gaid ->
44
+ JSONObject().apply {
45
+ appSetID?.also { put("appSetID", appSetID) }
46
+ generatedDeviceUUID?.also { put("generatedDeviceUUID", generatedDeviceUUID) }
47
+ gaid?.also { put("gaid", gaid) }
48
+ }
49
+ }.collect {
50
+ callback.invoke(it)
51
+ }
52
+ }
53
+ }
54
+
55
+ private fun requestAppSetID() : Flow<String?> = flow {
56
+ emit(null)
57
+ }
58
+
59
+ private fun requestGeneratedDeviceUUID() : Flow<String?> = callbackFlow {
60
+ Airbridge.fetchAirbridgeGeneratedUUID{
61
+ trySend(it)
62
+ }
63
+
64
+ awaitClose()
65
+ }
66
+
67
+ private fun requestGAID() : Flow<String?> = callbackFlow {
68
+ Airbridge.getDeviceInfo().getGoogleAdvertisingIdInfo(object : AirbridgeCallback<AdvertisingIdInfo> {
69
+ override fun onSuccess(result: AdvertisingIdInfo) {
70
+ trySend(result.id)
71
+ }
72
+
73
+ override fun onComplete() {
74
+ }
75
+
76
+ override fun onFailure(throwable: Throwable) {
77
+ trySend(null)
78
+ }
79
+ })
80
+
81
+ awaitClose()
82
+ }
83
+ }