Skip to content

Commit 7cc9a41

Browse files
committed
chore: wip
1 parent d15224a commit 7cc9a41

File tree

2 files changed

+237
-8
lines changed

2 files changed

+237
-8
lines changed

android/src/main/java/com/reactnativewebbrowser/NativeWebBrowserModule.kt

Lines changed: 234 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
package com.reactnativewebbrowser
22

3-
import com.facebook.react.bridge.Promise
4-
import com.facebook.react.bridge.ReactApplicationContext
5-
import com.facebook.react.bridge.ReactContextBaseJavaModule
6-
import com.facebook.react.bridge.ReactMethod
3+
import android.content.Intent
4+
import android.graphics.Color
5+
import android.net.Uri
6+
import android.os.Bundle
7+
import android.text.TextUtils
8+
import androidx.browser.customtabs.CustomTabsIntent
9+
import com.facebook.react.bridge.*
10+
import com.reactnativewebbrowser.error.CurrentActivityNotFoundException
11+
import com.reactnativewebbrowser.error.NoPreferredPackageFound
12+
import com.reactnativewebbrowser.error.PackageManagerNotFoundException
713

814
class NativeWebBrowserModule(reactContext: ReactApplicationContext) :
915
ReactContextBaseJavaModule(reactContext) {
1016

1117
val activityProvider = InternalActicityProvider(reactContext)
12-
val customTabsActivitiesHelper = InternalCustomTabsActivitiesHelper(activityProvider)
13-
val customTabsConnectionHelper = InternalCustomTabsConnectionHelper(reactContext)
18+
val customTabsActivitiesHelper =
19+
InternalCustomTabsActivitiesHelper(activityProvider)
20+
val customTabsConnectionHelper =
21+
InternalCustomTabsConnectionHelper(reactContext)
1422

1523
private val BROWSER_PACKAGE_KEY = "browserPackage"
1624
private val SERVICE_PACKAGE_KEY = "servicePackage"
@@ -45,5 +53,225 @@ class NativeWebBrowserModule(reactContext: ReactApplicationContext) :
4553

4654
}
4755

56+
@ExpoMethod
57+
fun warmUpAsync(packageName: String?, promise: Promise) {
58+
try {
59+
val packageName = givenOrPreferredPackageName(packageName)
60+
customTabsConnectionHelper.warmUp(packageName)
61+
val result = Bundle()
62+
result.putString(
63+
expo.modules.webbrowser.WebBrowserModule.SERVICE_PACKAGE_KEY,
64+
packageName
65+
)
66+
promise.resolve(result)
67+
} catch (ex: NoPreferredPackageFound) {
68+
promise.reject(ex)
69+
}
70+
}
71+
72+
@ExpoMethod
73+
fun coolDownAsync(packageName: String?, promise: Promise) {
74+
var packageName = packageName
75+
try {
76+
packageName = givenOrPreferredPackageName(packageName)
77+
if (mConnectionHelper.coolDown(packageName)) {
78+
val result = Bundle()
79+
result.putString(
80+
expo.modules.webbrowser.WebBrowserModule.SERVICE_PACKAGE_KEY,
81+
packageName
82+
)
83+
promise.resolve(result)
84+
} else {
85+
promise.resolve(Bundle())
86+
}
87+
} catch (ex: NoPreferredPackageFound) {
88+
promise.reject(ex)
89+
}
90+
}
91+
92+
@ExpoMethod
93+
fun mayInitWithUrlAsync(
94+
url: String?,
95+
packageName: String?,
96+
promise: Promise
97+
) {
98+
var packageName = packageName
99+
try {
100+
packageName = givenOrPreferredPackageName(packageName)
101+
mConnectionHelper.mayInitWithUrl(packageName, Uri.parse(url))
102+
val result = Bundle()
103+
result.putString(
104+
expo.modules.webbrowser.WebBrowserModule.SERVICE_PACKAGE_KEY,
105+
packageName
106+
)
107+
promise.resolve(result)
108+
} catch (ex: NoPreferredPackageFound) {
109+
promise.reject(ex)
110+
}
111+
}
112+
113+
@ExpoMethod
114+
fun getCustomTabsSupportingBrowsersAsync(promise: Promise) {
115+
try {
116+
val activities: ArrayList<String> =
117+
mCustomTabsResolver.getCustomTabsResolvingActivities()
118+
val services: ArrayList<String> =
119+
mCustomTabsResolver.getCustomTabsResolvingServices()
120+
val preferredPackage: String =
121+
mCustomTabsResolver.getPreferredCustomTabsResolvingActivity(activities)
122+
val defaultPackage: String =
123+
mCustomTabsResolver.getDefaultCustomTabsResolvingActivity()
124+
var defaultCustomTabsPackage: String? = null
125+
if (activities.contains(defaultPackage)) { // It might happen, that default activity does not support Chrome Tabs. Then it will be ResolvingActivity and we don't want to return it as a result.
126+
defaultCustomTabsPackage = defaultPackage
127+
}
128+
val result = Bundle()
129+
result.putStringArrayList(
130+
expo.modules.webbrowser.WebBrowserModule.BROWSER_PACKAGES_KEY,
131+
activities
132+
)
133+
result.putStringArrayList(
134+
expo.modules.webbrowser.WebBrowserModule.SERVICE_PACKAGES_KEY,
135+
services
136+
)
137+
result.putString(
138+
expo.modules.webbrowser.WebBrowserModule.PREFERRED_BROWSER_PACKAGE,
139+
preferredPackage
140+
)
141+
result.putString(
142+
expo.modules.webbrowser.WebBrowserModule.DEFAULT_BROWSER_PACKAGE,
143+
defaultCustomTabsPackage
144+
)
145+
promise.resolve(result)
146+
} catch (ex: CurrentActivityNotFoundException) {
147+
promise.reject(ex)
148+
} catch (ex: PackageManagerNotFoundException) {
149+
promise.reject(ex)
150+
}
151+
}
152+
153+
/**
154+
* @param url Url to be opened by WebBrowser
155+
* @param arguments Required arguments are:
156+
* toolbarColor: String;
157+
* browserPackage: String;
158+
* enableBarCollapsing: Boolean;
159+
* showTitle: Boolean;
160+
* enableDefaultShareMenuItem: Boolean;
161+
* showInRecents: Boolean;
162+
* @param promise
163+
*/
164+
@ExpoMethod
165+
fun openBrowserAsync(
166+
url: String?,
167+
arguments: ReadableArguments,
168+
promise: Promise
169+
) {
170+
val intent = createCustomTabsIntent(arguments)
171+
intent.data = Uri.parse(url)
172+
try {
173+
if (mCustomTabsResolver.canResolveIntent(intent)) {
174+
mCustomTabsResolver.startCustomTabs(intent)
175+
val result = Bundle()
176+
result.putString("type", "opened")
177+
promise.resolve(result)
178+
} else {
179+
promise.reject(
180+
expo.modules.webbrowser.WebBrowserModule.ERROR_CODE,
181+
"No matching activity!"
182+
)
183+
}
184+
} catch (ex: CurrentActivityNotFoundException) {
185+
promise.reject(ex)
186+
} catch (ex: PackageManagerNotFoundException) {
187+
promise.reject(ex)
188+
}
189+
}
190+
191+
private fun createCustomTabsIntent(arguments: ReadableMap): Intent {
192+
val builder = CustomTabsIntent.Builder()
193+
val color: String? =
194+
arguments.getString(TOOLBAR_COLOR_KEY)
195+
val secondaryColor: String? =
196+
arguments.getString(SECONDARY_TOOLBAR_COLOR_KEY)
197+
val packageName: String? =
198+
arguments.getString(BROWSER_PACKAGE_KEY)
199+
try {
200+
if (!TextUtils.isEmpty(color)) {
201+
val intColor = Color.parseColor(color)
202+
builder.setToolbarColor(intColor)
203+
}
204+
if (!TextUtils.isEmpty(secondaryColor)) {
205+
val intSecondaryColor = Color.parseColor(secondaryColor)
206+
builder.setSecondaryToolbarColor(intSecondaryColor)
207+
}
208+
} catch (ignored: IllegalArgumentException) {
209+
}
210+
builder.setShowTitle(
211+
if (!arguments.hasKey(SHOW_TITLE_KEY) || arguments.isNull(SHOW_TITLE_KEY)) {
212+
false
213+
} else {
214+
arguments.getBoolean(
215+
SHOW_TITLE_KEY
216+
)
217+
}
218+
)
219+
if (arguments.hasKey(DEFAULT_SHARE_MENU_ITEM) && arguments.getBoolean(
220+
DEFAULT_SHARE_MENU_ITEM
221+
)
222+
) {
223+
builder.addDefaultShareMenuItem()
224+
}
225+
val intent = builder.build().intent
226+
227+
// We cannot use builder's method enableUrlBarHiding, because there is no corresponding disable method and some browsers enables it by default.
228+
intent.putExtra(
229+
CustomTabsIntent.EXTRA_ENABLE_URLBAR_HIDING,
230+
arguments.getBoolean(
231+
ENABLE_BAR_COLLAPSING_KEY,
232+
false
233+
)
234+
)
235+
if (!TextUtils.isEmpty(packageName)) {
236+
intent.setPackage(packageName)
237+
}
238+
if (arguments.getBoolean(
239+
CREATE_TASK,
240+
true
241+
)
242+
) {
243+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
244+
if (!arguments.getBoolean(
245+
SHOW_IN_RECENTS,
246+
false
247+
)
248+
) {
249+
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
250+
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
251+
}
252+
}
253+
return intent
254+
}
255+
256+
private fun givenOrPreferredPackageName(packageName: String?): String? {
257+
var processedPackageName = packageName
258+
try {
259+
if (TextUtils.isEmpty(processedPackageName)) {
260+
processedPackageName =
261+
customTabsActivitiesHelper.getPreferredCustomTabsResolvingActivity(
262+
null
263+
)
264+
}
265+
} catch (ex: CurrentActivityNotFoundException) {
266+
throw NoPreferredPackageFound(NO_PREFERRED_PACKAGE_MSG)
267+
} catch (ex: PackageManagerNotFoundException) {
268+
throw NoPreferredPackageFound(NO_PREFERRED_PACKAGE_MSG)
269+
}
270+
if (TextUtils.isEmpty(processedPackageName)) {
271+
throw NoPreferredPackageFound(NO_PREFERRED_PACKAGE_MSG)
272+
}
273+
return processedPackageName
274+
}
275+
48276

49277
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.reactnativewebbrowser.error
22

3-
class NoPreferredPackageFound :
4-
ReactNativeWebBrowserException("Preferred package not found.") {
3+
class NoPreferredPackageFound(str: String) :
4+
ReactNativeWebBrowserException(str) {
5+
constructor() : this("PREFERRED_PACKAGE_NOT_FOUND") {}
56
}

0 commit comments

Comments
 (0)