package com.contentsquare.rn.csq import android.app.Activity import android.graphics.Bitmap import android.os.Build import android.util.Log import android.webkit.WebView import android.webkit.WebViewClient import com.contentsquare.CSQ import com.contentsquare.android.R import com.contentsquare.rn.utils.ReactNativeUiThreadUtil import com.contentsquare.rn.utils.ReactNativeViewFinder import com.contentsquare.rn.utils.VersionUtils.isApiLevelAtLeast import com.contentsquare.rn.utils.WebViewUtils.getWebViewClient import com.contentsquare.rn.webview.BridgeWebViewClient import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.modules.core.DeviceEventManagerModule class CSQWebView( private val reactContext: ReactApplicationContext, private val reactNativeUiThreadUtil: ReactNativeUiThreadUtil, private val reactNativeViewFinder: ReactNativeViewFinder, ) { fun registerWebView (webViewTag: Int) { val activity: Activity = reactContext.getCurrentActivity() ?: return reactNativeUiThreadUtil.runOnUiThread { reactNativeViewFinder.findWebView( reactContext, webViewTag ) { webView: WebView? -> Log.i("CSLIB", "WebView found in native bridge. Ready to be injected") CSQ.registerWebView(prepareWebView(activity, webView!!)) // getting React Native's webview client before setting a new webview client val rnWebViewClient = getWebViewClient(webView) // replacing Native SDK webview client with custom one handleBlankPageRemoval(webView, rnWebViewClient) reactContext .getJSModule( DeviceEventManagerModule.RCTDeviceEventEmitter::class.java ) .emit("onCSQWebViewInjected", null) } } } fun unregisterWebView (webViewTag: Int) { val activity = reactContext.currentActivity ?: return reactNativeUiThreadUtil.runOnUiThread { reactNativeViewFinder.findWebView( reactContext, webViewTag ) { webView: WebView? -> Log.i("CSLIB", "WebView found in native bridge. Ready to remove injection") CSQ.unregisterWebView(prepareWebView(activity, webView!!)) } } } private fun prepareWebView(activity: Activity, webView: WebView): WebView { webView.setTag(R.string.contentsquare_react_native_web_view_activity_tag, activity) return webView } /* * removes "about:blank" from history. This page is added due to the current implementation in RN * * this method only works for API levels 26 and up * */ private fun handleBlankPageRemoval(webView: WebView, rnWebViewClient: WebViewClient?) { if (isApiLevelAtLeast(Build.VERSION_CODES.O)) { if (rnWebViewClient != null) { webView.webViewClient = object : BridgeWebViewClient(rnWebViewClient) { override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { super.onPageStarted(view, url, favicon) val backForwardList = webView.copyBackForwardList() // We need to remove the blank page introduced when loading the first time with "undefined" url from JS if (backForwardList.size == 2 && "about:blank" == backForwardList.getItemAtIndex( 0 ).originalUrl ) { webView.clearHistory() } } } } else { Log.i("CSLIB", "Handling blank page removal not performed: web client not found") } } else { Log.i("CSLIB", "Handling blank page removal not performed: API leve lower than 26") } } }