Convert K9WebViewClient
to Kotlin
This commit is contained in:
parent
6a202800f3
commit
30efd5051f
1 changed files with 95 additions and 114 deletions
|
@ -1,142 +1,123 @@
|
|||
package com.fsck.k9.view;
|
||||
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.Browser;
|
||||
import android.text.TextUtils;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebResourceResponse;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.fsck.k9.mailstore.AttachmentResolver;
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.view.MessageWebView.OnPageFinishedListener;
|
||||
import timber.log.Timber;
|
||||
package com.fsck.k9.view
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.provider.Browser
|
||||
import android.webkit.WebResourceRequest
|
||||
import android.webkit.WebResourceResponse
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.fsck.k9.logging.Timber
|
||||
import com.fsck.k9.mailstore.AttachmentResolver
|
||||
import com.fsck.k9.ui.R
|
||||
import com.fsck.k9.view.MessageWebView.OnPageFinishedListener
|
||||
|
||||
/**
|
||||
* {@link WebViewClient} that intercepts requests for {@code cid:} URIs to load the respective body part.
|
||||
* [WebViewClient] that intercepts requests for `cid:` URIs to load the respective body part.
|
||||
*/
|
||||
public class K9WebViewClient extends WebViewClient {
|
||||
private static final String CID_SCHEME = "cid";
|
||||
private static final WebResourceResponse RESULT_DO_NOT_INTERCEPT = null;
|
||||
private static final WebResourceResponse RESULT_DUMMY_RESPONSE = new WebResourceResponse(null, null, null);
|
||||
private OnPageFinishedListener onPageFinishedListener;
|
||||
internal class K9WebViewClient(
|
||||
private val attachmentResolver: AttachmentResolver?,
|
||||
) : WebViewClient() {
|
||||
private var onPageFinishedListener: OnPageFinishedListener? = null
|
||||
|
||||
|
||||
@Nullable
|
||||
private final AttachmentResolver attachmentResolver;
|
||||
|
||||
|
||||
public static K9WebViewClient newInstance(@Nullable AttachmentResolver attachmentResolver) {
|
||||
return new K9WebViewClient(attachmentResolver);
|
||||
@Deprecated("Deprecated in parent class")
|
||||
override fun shouldOverrideUrlLoading(webView: WebView, url: String): Boolean {
|
||||
return shouldOverrideUrlLoading(webView, Uri.parse(url))
|
||||
}
|
||||
|
||||
|
||||
private K9WebViewClient(@Nullable AttachmentResolver attachmentResolver) {
|
||||
this.attachmentResolver = attachmentResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
|
||||
return shouldOverrideUrlLoading(webView, Uri.parse(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request) {
|
||||
return shouldOverrideUrlLoading(webView, request.getUrl());
|
||||
override fun shouldOverrideUrlLoading(webView: WebView, request: WebResourceRequest): Boolean {
|
||||
return shouldOverrideUrlLoading(webView, request.url)
|
||||
}
|
||||
|
||||
private boolean shouldOverrideUrlLoading(WebView webView, Uri uri) {
|
||||
if (CID_SCHEME.equals(uri.getScheme())) {
|
||||
return false;
|
||||
}
|
||||
private fun shouldOverrideUrlLoading(webView: WebView, uri: Uri): Boolean {
|
||||
if (uri.scheme == CID_SCHEME) return false
|
||||
|
||||
Context context = webView.getContext();
|
||||
Intent intent = createBrowserViewIntent(uri, context);
|
||||
val context = webView.context
|
||||
val intent = createBrowserViewIntent(uri, context)
|
||||
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
} catch (ActivityNotFoundException ex) {
|
||||
Toast.makeText(context, R.string.error_activity_not_found, Toast.LENGTH_LONG).show();
|
||||
context.startActivity(intent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
Timber.d(e, "Couldn't open URL: %s", uri)
|
||||
Toast.makeText(context, R.string.error_activity_not_found, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
private Intent createBrowserViewIntent(Uri uri, Context context) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
intent.addCategory(Intent.CATEGORY_BROWSABLE);
|
||||
intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
|
||||
intent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
|
||||
return intent;
|
||||
}
|
||||
private fun createBrowserViewIntent(uri: Uri, context: Context): Intent {
|
||||
return Intent(Intent.ACTION_VIEW, uri).apply {
|
||||
putExtra(Browser.EXTRA_APPLICATION_ID, context.packageName)
|
||||
putExtra(Browser.EXTRA_CREATE_NEW_TAB, true)
|
||||
|
||||
public WebResourceResponse shouldInterceptRequest(WebView webView, WebResourceRequest request) {
|
||||
Uri uri = request.getUrl();
|
||||
if (!CID_SCHEME.equals(uri.getScheme())) {
|
||||
return RESULT_DO_NOT_INTERCEPT;
|
||||
}
|
||||
|
||||
if (attachmentResolver == null) {
|
||||
return RESULT_DUMMY_RESPONSE;
|
||||
}
|
||||
|
||||
String cid = uri.getSchemeSpecificPart();
|
||||
if (TextUtils.isEmpty(cid)) {
|
||||
return RESULT_DUMMY_RESPONSE;
|
||||
}
|
||||
|
||||
Uri attachmentUri = attachmentResolver.getAttachmentUriForContentId(cid);
|
||||
if (attachmentUri == null) {
|
||||
return RESULT_DUMMY_RESPONSE;
|
||||
}
|
||||
|
||||
Context context = webView.getContext();
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
try {
|
||||
String mimeType = contentResolver.getType(attachmentUri);
|
||||
InputStream inputStream = contentResolver.openInputStream(attachmentUri);
|
||||
|
||||
WebResourceResponse webResourceResponse = new WebResourceResponse(mimeType, null, inputStream);
|
||||
addCacheControlHeader(webResourceResponse);
|
||||
return webResourceResponse;
|
||||
} catch (Exception e) {
|
||||
Timber.e(e, "Error while intercepting URI: %s", uri);
|
||||
return RESULT_DUMMY_RESPONSE;
|
||||
addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
|
||||
}
|
||||
}
|
||||
|
||||
private void addCacheControlHeader(WebResourceResponse response) {
|
||||
Map<String, String> headers = Collections.singletonMap("Cache-Control", "no-store");
|
||||
response.setResponseHeaders(headers);
|
||||
override fun shouldInterceptRequest(webView: WebView, request: WebResourceRequest): WebResourceResponse? {
|
||||
val uri = request.url
|
||||
|
||||
return if (uri.scheme == CID_SCHEME) {
|
||||
handleCidUri(uri, webView)
|
||||
} else {
|
||||
RESULT_DO_NOT_INTERCEPT
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnPageFinishedListener(OnPageFinishedListener onPageFinishedListener) {
|
||||
this.onPageFinishedListener = onPageFinishedListener;
|
||||
private fun handleCidUri(uri: Uri, webView: WebView): WebResourceResponse {
|
||||
val attachmentUri = getAttachmentUriFromCidUri(uri) ?: return RESULT_DUMMY_RESPONSE
|
||||
|
||||
val context = webView.context
|
||||
val contentResolver = context.contentResolver
|
||||
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
return try {
|
||||
val mimeType = contentResolver.getType(attachmentUri)
|
||||
val inputStream = contentResolver.openInputStream(attachmentUri)
|
||||
|
||||
WebResourceResponse(mimeType, null, inputStream).apply {
|
||||
addCacheControlHeader()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error while intercepting URI: %s", uri)
|
||||
RESULT_DUMMY_RESPONSE
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
super.onPageFinished(view, url);
|
||||
if (onPageFinishedListener != null) {
|
||||
onPageFinishedListener.onPageFinished();
|
||||
private fun getAttachmentUriFromCidUri(uri: Uri): Uri? {
|
||||
return uri.schemeSpecificPart
|
||||
?.let { cid -> attachmentResolver?.getAttachmentUriForContentId(cid) }
|
||||
}
|
||||
|
||||
private fun WebResourceResponse.addCacheControlHeader() {
|
||||
responseHeaders = mapOf("Cache-Control" to "no-store")
|
||||
}
|
||||
|
||||
fun setOnPageFinishedListener(onPageFinishedListener: OnPageFinishedListener?) {
|
||||
this.onPageFinishedListener = onPageFinishedListener
|
||||
}
|
||||
|
||||
override fun onPageFinished(view: WebView, url: String) {
|
||||
super.onPageFinished(view, url)
|
||||
|
||||
onPageFinishedListener?.onPageFinished()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val CID_SCHEME = "cid"
|
||||
|
||||
private val RESULT_DO_NOT_INTERCEPT: WebResourceResponse? = null
|
||||
private val RESULT_DUMMY_RESPONSE = WebResourceResponse(null, null, null)
|
||||
|
||||
fun newInstance(attachmentResolver: AttachmentResolver?): K9WebViewClient {
|
||||
return K9WebViewClient(attachmentResolver)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue