package eu.faircode.email; /* This file is part of FairEmail. FairEmail is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. FairEmail is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with FairEmail. If not, see . Copyright 2018-2022 by Marcel Bokhorst (M66B) */ import android.Manifest; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.webkit.WebSettings; import android.webkit.WebView; import androidx.annotation.NonNull; import androidx.constraintlayout.widget.Group; import androidx.preference.PreferenceManager; import com.google.android.material.snackbar.Snackbar; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import java.io.FileNotFoundException; import java.io.InputStream; import java.nio.charset.StandardCharsets; public class ActivityAMP extends ActivityBase { private WebView wvAmp; private ContentLoadingProgressBar pbWait; private Group grpReady; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getSupportActionBar().setIcon(R.drawable.twotone_bolt_24); getSupportActionBar().setSubtitle("AMP"); View view = LayoutInflater.from(this).inflate(R.layout.activity_amp, null); setContentView(view); wvAmp = findViewById(R.id.wvAmp); pbWait = findViewById(R.id.pbWait); grpReady = findViewById(R.id.grpReady); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); boolean safe_browsing = prefs.getBoolean("safe_browsing", false); WebSettings settings = wvAmp.getSettings(); settings.setUserAgentString(WebViewEx.getUserAgent(this, wvAmp)); settings.setUseWideViewPort(true); settings.setLoadWithOverviewMode(true); settings.setBuiltInZoomControls(true); settings.setDisplayZoomControls(false); settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING); settings.setAllowFileAccess(false); settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) settings.setSafeBrowsingEnabled(safe_browsing); settings.setLoadsImagesAutomatically(true); settings.setBlockNetworkLoads(false); settings.setBlockNetworkImage(false); settings.setJavaScriptEnabled(true); // Initialize grpReady.setVisibility(View.GONE); load(); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); load(); } private void load() { Uri uri = getIntent().getData(); Log.i("AMP uri=" + uri); Bundle args = new Bundle(); args.putParcelable("uri", uri); new SimpleTask() { @Override protected void onPreExecute(Bundle args) { pbWait.setVisibility(View.VISIBLE); } @Override protected void onPostExecute(Bundle args) { pbWait.setVisibility(View.GONE); } @Override protected String onExecute(Context context, Bundle args) throws Throwable { Uri uri = args.getParcelable("uri"); if (uri == null) throw new FileNotFoundException(); if (!"content".equals(uri.getScheme()) && !Helper.hasPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE)) { Log.w("AMP uri=" + uri); throw new IllegalArgumentException(context.getString(R.string.title_no_stream)); } String html; ContentResolver resolver = context.getContentResolver(); try (InputStream is = resolver.openInputStream(uri)) { html = Helper.readStream(is); } Document d = JsoupEx.parse(html); for (Element script : d.select("script")) { String src = script.attr("src"); Uri u = Uri.parse(src); if (!u.isHierarchical() || !"cdn.ampproject.org".equals(u.getHost())) script.removeAttr("src"); } return d.html(); } @Override protected void onExecuted(Bundle args, String amp) { wvAmp.loadDataWithBaseURL(null, amp, "text/html", StandardCharsets.UTF_8.name(), null); grpReady.setVisibility(View.VISIBLE); } @Override protected void onException(Bundle args, @NonNull Throwable ex) { if (ex instanceof IllegalArgumentException) Snackbar.make(findViewById(android.R.id.content), ex.getMessage(), Snackbar.LENGTH_LONG) .setGestureInsetBottomIgnored(true).show(); else Log.unexpectedError(getSupportFragmentManager(), ex, false); } }.execute(this, args, "amp:decode"); } }