Browse Source

Simplified LightningView with externalized XXXClients

master
Stefano Pacifici 9 years ago
parent
commit
6749ca39b8
  1. 196
      app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java
  2. 32
      app/src/main/java/acr/browser/lightning/activity/TabsManager.java
  3. 7
      app/src/main/java/acr/browser/lightning/app/AppComponent.java
  4. 22
      app/src/main/java/acr/browser/lightning/bus/BookmarkEvents.java
  5. 42
      app/src/main/java/acr/browser/lightning/bus/BrowserEvents.java
  6. 2
      app/src/main/java/acr/browser/lightning/constant/HistoryPage.java
  7. 14
      app/src/main/java/acr/browser/lightning/database/HistoryDatabase.java
  8. 124
      app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java
  9. 8
      app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java
  10. 19
      app/src/main/java/acr/browser/lightning/object/SearchAdapter.java
  11. 3
      app/src/main/java/acr/browser/lightning/utils/WebUtils.java
  12. 234
      app/src/main/java/acr/browser/lightning/view/LightningChromeClient.java
  13. 555
      app/src/main/java/acr/browser/lightning/view/LightningView.java
  14. 66
      app/src/main/java/acr/browser/lightning/view/LightningViewTitle.java
  15. 276
      app/src/main/java/acr/browser/lightning/view/LightningWebClient.java

196
app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java

@ -18,14 +18,8 @@ import android.content.IntentFilter; @@ -18,14 +18,8 @@ import android.content.IntentFilter;
import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
@ -38,17 +32,13 @@ import android.provider.MediaStore; @@ -38,17 +32,13 @@ import android.provider.MediaStore;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.graphics.Palette;
import android.support.v7.graphics.drawable.DrawerArrowDrawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.KeyEvent;
@ -76,7 +66,6 @@ import android.webkit.ValueCallback; @@ -76,7 +66,6 @@ import android.webkit.ValueCallback;
import android.webkit.WebChromeClient.CustomViewCallback;
import android.webkit.WebIconDatabase;
import android.webkit.WebView;
import android.webkit.WebView.HitTestResult;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
@ -95,11 +84,7 @@ import com.squareup.otto.Bus; @@ -95,11 +84,7 @@ import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
@ -115,7 +100,7 @@ import acr.browser.lightning.constant.HistoryPage; @@ -115,7 +100,7 @@ import acr.browser.lightning.constant.HistoryPage;
import acr.browser.lightning.controller.BrowserController;
import acr.browser.lightning.database.BookmarkManager;
import acr.browser.lightning.database.HistoryDatabase;
import acr.browser.lightning.dialog.BookmarksDialogBuilder;
import acr.browser.lightning.dialog.LightningDialogBuilder;
import acr.browser.lightning.fragment.TabsFragment;
import acr.browser.lightning.object.SearchAdapter;
import acr.browser.lightning.preference.PreferenceManager;
@ -166,10 +151,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -166,10 +151,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mCurrentUiColor = Color.BLACK;
private String mSearchText, mUntitledTitle, mHomepage, mCameraPhotoPath;
// Storage
private HistoryDatabase mHistoryDatabase;
// The singleton BookmarkManager
@Inject
BookmarkManager bookmarkManager;
@ -182,7 +163,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -182,7 +163,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
BookmarkPage bookmarkPage;
@Inject
BookmarksDialogBuilder bookmarksDialogBuilder;
LightningDialogBuilder bookmarksDialogBuilder;
@Inject
TabsManager tabsManager;
@ -190,6 +171,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -190,6 +171,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
@Inject
PreferenceManager mPreferences;
@Inject
HistoryDatabase mHistoryDatabase;
// Image
private Bitmap mWebpageBitmap;
private final ColorDrawable mBackground = new ColorDrawable();
@ -280,8 +264,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -280,8 +264,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mToolbarLayout.removeView(findViewById(R.id.tabs_toolbar_container));
}
mHistoryDatabase = HistoryDatabase.getInstance();
if (actionBar == null)
return;
@ -356,7 +338,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -356,7 +338,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
WebIconDatabase.getInstance().open(getDir("icons", MODE_PRIVATE).getPath());
}
// initializeTabs();
tabsManager.restoreTabs(this, mDarkTheme, isIncognito());
// At this point we always have at least a tab in the tab manager
showTab(0);
mProxyUtils.checkForProxy(this);
}
@ -565,45 +549,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -565,45 +549,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
}
/* TODO !!!! THIS MUST BY RESTORED ASAP !!!!
void restoreOrNewTab() {
mIdGenerator = 0;
String url = null;
if (getIntent() != null) {
url = getIntent().getDataString();
if (url != null) {
if (url.startsWith(Constants.FILE)) {
Utils.showSnackbar(this, R.string.message_blocked_local);
url = null;
}
}
}
if (mPreferences.getRestoreLostTabsEnabled()) {
String mem = mPreferences.getMemoryUrl();
mPreferences.setMemoryUrl("");
String[] array = Utils.getArray(mem);
int count = 0;
for (String urlString : array) {
if (!urlString.isEmpty()) {
if (url != null && url.compareTo(urlString) == 0) {
url = null;
}
newTab(urlString, true);
count++;
}
}
if (url != null) {
newTab(url, true);
} else if (count == 0) {
newTab(null, true);
}
} else {
newTab(url, true);
}
}
*/
private void initializePreferences() {
final LightningView currentView = tabsManager.getCurrentTab();
final WebView currentWebView = currentView.getWebView();
@ -1001,7 +946,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1001,7 +946,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
return false;
}
mIsNewIntent = false;
LightningView startingTab = tabsManager.newTab(mActivity, url, mDarkTheme, isIncognito(), this);
LightningView startingTab = tabsManager.newTab(this, url, mDarkTheme, isIncognito());
if (mIdGenerator == 0) {
startingTab.resumeTimers();
}
@ -1227,7 +1172,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1227,7 +1172,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
currentTab.resumeTimers();
currentTab.onResume();
}
mHistoryDatabase = HistoryDatabase.getInstance();
initializePreferences();
tabsManager.resume(this);
@ -1366,9 +1310,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1366,9 +1310,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
@Override
public void run() {
try {
if (mHistoryDatabase == null) {
mHistoryDatabase = HistoryDatabase.getInstance();
}
mHistoryDatabase.visitHistoryItem(url, title);
} catch (IllegalStateException e) {
Log.e(Constants.TAG, "IllegalStateException in updateHistory", e);
@ -1848,107 +1789,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1848,107 +1789,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
}
private void longPressHistoryLink(final String url) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final LightningView currentTab = tabsManager.getCurrentTab();
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
newTab(url, false);
mDrawerLayout.closeDrawers();
break;
case DialogInterface.BUTTON_NEGATIVE:
mHistoryDatabase.deleteHistoryItem(url);
openHistory();
break;
case DialogInterface.BUTTON_NEUTRAL:
if (currentTab != null) {
loadUrlInCurrentView(url);
}
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(R.string.action_history)
.setMessage(R.string.dialog_history_long_press)
.setCancelable(true)
.setPositiveButton(R.string.action_new_tab, dialogClickListener)
.setNegativeButton(R.string.action_delete, dialogClickListener)
.setNeutralButton(R.string.action_open, dialogClickListener)
.show();
}
private void longPressImage(final String url) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final LightningView currentTab = tabsManager.getCurrentTab();
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
newTab(url, false);
break;
case DialogInterface.BUTTON_NEGATIVE:
loadUrlInCurrentView(url);
break;
case DialogInterface.BUTTON_NEUTRAL:
if (API > 8) {
Utils.downloadFile(mActivity, url,
currentTab.getUserAgent(), "attachment");
}
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(url.replace(Constants.HTTP, ""))
.setCancelable(true)
.setMessage(R.string.dialog_image)
.setPositiveButton(R.string.action_new_tab, dialogClickListener)
.setNegativeButton(R.string.action_open, dialogClickListener)
.setNeutralButton(R.string.action_download, dialogClickListener)
.show();
}
private void longPressLink(final String url) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
newTab(url, false);
break;
case DialogInterface.BUTTON_NEGATIVE:
loadUrlInCurrentView(url);
break;
case DialogInterface.BUTTON_NEUTRAL:
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label", url);
clipboard.setPrimaryClip(clip);
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); // dialog
builder.setTitle(url)
.setCancelable(true)
.setMessage(R.string.dialog_link)
.setPositiveButton(R.string.action_new_tab, dialogClickListener)
.setNegativeButton(R.string.action_open, dialogClickListener)
.setNeutralButton(R.string.action_copy, dialogClickListener)
.show();
}
/**
* This method lets the search bar know that the page is currently loading
* and that it should display the stop icon to indicate to the user that
@ -2058,13 +1898,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -2058,13 +1898,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
private final Object busEventListener = new Object() {
/**
* Load the given bookmark in the current tab, used by the the
* {@link acr.browser.lightning.fragment.BookmarksFragment}
* Load the given url in the current tab, used by the the
* {@link acr.browser.lightning.fragment.BookmarksFragment} and by the
* {@link LightningDialogBuilder}
* @param event The event as it comes from the bus
*/
@Subscribe
public void loadBookmarkInCurrentTab(final BookmarkEvents.Clicked event) {
loadUrlInCurrentView(event.bookmark.getUrl());
public void loadUrlInCurrentTab(final BrowserEvents.OpenUrlInCurrentTab event) {
loadUrlInCurrentView(event.url);
// keep any jank from happening when the drawer is closed after the
// URL starts to load
final Handler handler = new Handler();
@ -2077,13 +1918,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -2077,13 +1918,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
/**
* Load the given bookmark in a new tab, used by the the
* {@link acr.browser.lightning.fragment.BookmarksFragment}
* Load the given url in a new tab, used by the the
* {@link acr.browser.lightning.fragment.BookmarksFragment} and by the
* {@link LightningDialogBuilder}
* @param event The event as it comes from the bus
*/
@Subscribe
public void loadBookmarkInNewTab(final BookmarkEvents.AsNewTab event) {
BrowserActivity.this.newTab(event.bookmark.getUrl(), true);
public void loadUrlInNewTab(final BrowserEvents.OpenUrlInNewTab event) {
BrowserActivity.this.newTab(event.url, true);
mDrawerLayout.closeDrawers();
}

32
app/src/main/java/acr/browser/lightning/activity/TabsManager.java

@ -13,6 +13,7 @@ import javax.inject.Singleton; @@ -13,6 +13,7 @@ import javax.inject.Singleton;
import acr.browser.lightning.controller.BrowserController;
import acr.browser.lightning.preference.PreferenceManager;
import acr.browser.lightning.utils.Utils;
import acr.browser.lightning.view.LightningView;
/**
@ -26,7 +27,30 @@ public class TabsManager { @@ -26,7 +27,30 @@ public class TabsManager {
private LightningView mCurrentTab;
@Inject
public TabsManager(final Context context, final PreferenceManager preferenceManager) {
PreferenceManager mPreferenceManager;
@Inject
public TabsManager() {
}
public void restoreTabs(BrowserActivity activity, boolean darkTheme, boolean incognito) {
mWebViewList.clear();
mCurrentTab = null;
if (!incognito && mPreferenceManager.getRestoreLostTabsEnabled()) {
final String mem = mPreferenceManager.getMemoryUrl();
mPreferenceManager.setMemoryUrl("");
String[] array = Utils.getArray(mem);
int count = 0;
for (String urlString : array) {
if (!urlString.isEmpty()) {
newTab(activity, urlString, darkTheme, incognito);
}
}
}
if (mWebViewList.size() == 0) {
newTab(activity, null, darkTheme, incognito);
}
// mCurrentTab = mWebViewList.get(0);
}
/**
@ -112,13 +136,11 @@ public class TabsManager { @@ -112,13 +136,11 @@ public class TabsManager {
* @param url
* @param darkTheme
* @param isIncognito
* @param controller
* @return
*/
public synchronized LightningView newTab(final Activity activity,
public synchronized LightningView newTab(final BrowserActivity activity,
final String url, final boolean darkTheme,
final boolean isIncognito,
final BrowserController controller) {
final boolean isIncognito) {
final LightningView tab = new LightningView(activity, url, darkTheme, isIncognito);
mWebViewList.add(tab);
return tab;

7
app/src/main/java/acr/browser/lightning/app/AppComponent.java

@ -8,7 +8,8 @@ import javax.inject.Singleton; @@ -8,7 +8,8 @@ import javax.inject.Singleton;
import acr.browser.lightning.activity.BrowserActivity;
import acr.browser.lightning.constant.BookmarkPage;
import acr.browser.lightning.dialog.BookmarksDialogBuilder;
import acr.browser.lightning.database.HistoryDatabase;
import acr.browser.lightning.dialog.LightningDialogBuilder;
import acr.browser.lightning.fragment.BookmarkSettingsFragment;
import acr.browser.lightning.fragment.BookmarksFragment;
import acr.browser.lightning.fragment.LightningPreferenceFragment;
@ -33,7 +34,7 @@ public interface AppComponent { @@ -33,7 +34,7 @@ public interface AppComponent {
void inject(SearchAdapter adapter);
void inject(BookmarksDialogBuilder builder);
void inject(LightningDialogBuilder builder);
void inject(BookmarkPage bookmarkPage);
@ -47,6 +48,8 @@ public interface AppComponent { @@ -47,6 +48,8 @@ public interface AppComponent {
Bus getBus();
HistoryDatabase getHistoryDatabase();
Context getApplicationContext();
void inject(LightningView lightningView);

22
app/src/main/java/acr/browser/lightning/bus/BookmarkEvents.java

@ -11,28 +11,6 @@ public final class BookmarkEvents { @@ -11,28 +11,6 @@ public final class BookmarkEvents {
// No instances
}
/**
* A bookmark was clicked
*/
public final static class Clicked {
public final HistoryItem bookmark;
public Clicked(final HistoryItem bookmark) {
this.bookmark = bookmark;
}
}
/**
* The user ask to open the bookmark as new tab
*/
public final static class AsNewTab {
public final HistoryItem bookmark;
public AsNewTab(final HistoryItem bookmark) {
this.bookmark = bookmark;
}
}
/**
* The user ask to delete the selected bookmark
*/

42
app/src/main/java/acr/browser/lightning/bus/BrowserEvents.java

@ -1,11 +1,7 @@ @@ -1,11 +1,7 @@
package acr.browser.lightning.bus;
import android.support.annotation.IdRes;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import acr.browser.lightning.R;
/**
* Created by Stefano Pacifici on 26/08/15.
*/
@ -21,9 +17,9 @@ public final class BrowserEvents { @@ -21,9 +17,9 @@ public final class BrowserEvents {
* result is a new bookmark added.
*/
public static class AddBookmark {
public final String title, url;
public final java.lang.String title, url;
public AddBookmark(final String title, final String url) {
public AddBookmark(final java.lang.String title, final java.lang.String url) {
this.title = title;
this.url = url;
}
@ -34,9 +30,9 @@ public final class BrowserEvents { @@ -34,9 +30,9 @@ public final class BrowserEvents {
* {@link acr.browser.lightning.fragment.BookmarksFragment} interface.
*/
public static class CurrentPageUrl {
public final String url;
public final java.lang.String url;
public CurrentPageUrl(final String url) {
public CurrentPageUrl(final java.lang.String url) {
this.url = url;
}
}
@ -53,15 +49,19 @@ public final class BrowserEvents { @@ -53,15 +49,19 @@ public final class BrowserEvents {
public static class TabsChanged {
}
/**
*
*/
/**
* Notify the Browser to display a SnackBar in the main activity
*/
public static class ShowSnackBarMessage {
public final String message;
public final java.lang.String message;
@StringRes
public final int stringRes;
public ShowSnackBarMessage(final String message) {
public ShowSnackBarMessage(final java.lang.String message) {
this.message = message;
this.stringRes = -1;
}
@ -71,4 +71,26 @@ public final class BrowserEvents { @@ -71,4 +71,26 @@ public final class BrowserEvents {
this.stringRes = stringRes;
}
}
/**
* The user want to open the given url in the current tab
*/
public final static class OpenUrlInCurrentTab {
public final String url;
public OpenUrlInCurrentTab(final String url) {
this.url = url;
}
}
/**
* The user ask to open the given url as new tab
*/
public final static class OpenUrlInNewTab {
public final String url;
public OpenUrlInNewTab(final String url) {
this.url = url;
}
}
}

2
app/src/main/java/acr/browser/lightning/constant/HistoryPage.java

@ -66,7 +66,7 @@ public class HistoryPage { @@ -66,7 +66,7 @@ public class HistoryPage {
}
private static List<HistoryItem> getWebHistory(Context context) {
HistoryDatabase databaseHandler = HistoryDatabase.getInstance();
HistoryDatabase databaseHandler = BrowserApp.getAppComponent().getHistoryDatabase();
return databaseHandler.getLastHundredItems();
}
}

14
app/src/main/java/acr/browser/lightning/database/HistoryDatabase.java

@ -12,9 +12,13 @@ import android.database.sqlite.SQLiteOpenHelper; @@ -12,9 +12,13 @@ import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import acr.browser.lightning.R;
import acr.browser.lightning.app.BrowserApp;
@Singleton
public class HistoryDatabase extends SQLiteOpenHelper {
// All Static variables
@ -39,14 +43,8 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -39,14 +43,8 @@ public class HistoryDatabase extends SQLiteOpenHelper {
private boolean mLock;
public static HistoryDatabase getInstance() {
if (mInstance == null || mInstance.isClosed()) {
mInstance = new HistoryDatabase(BrowserApp.getAppContext());
}
return mInstance;
}
private HistoryDatabase(Context context) {
@Inject
public HistoryDatabase(Context context) {
super(context.getApplicationContext(), DATABASE_NAME, null, DATABASE_VERSION);
mDatabase = this.getWritableDatabase();
}

124
app/src/main/java/acr/browser/lightning/dialog/BookmarksDialogBuilder.java → app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java

@ -1,8 +1,13 @@ @@ -1,8 +1,13 @@
package acr.browser.lightning.dialog;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.widget.ArrayAdapter;
@ -19,24 +24,32 @@ import javax.inject.Inject; @@ -19,24 +24,32 @@ import javax.inject.Inject;
import acr.browser.lightning.R;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.bus.BookmarkEvents;
import acr.browser.lightning.bus.BrowserEvents;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.constant.HistoryPage;
import acr.browser.lightning.database.BookmarkManager;
import acr.browser.lightning.database.HistoryDatabase;
import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.utils.Utils;
/**
* TODO Rename this class it doesn't build dialogs only for bookmarks
*
* Created by Stefano Pacifici on 02/09/15, based on Anthony C. Restaino's code.
*/
public class BookmarksDialogBuilder {
public class LightningDialogBuilder {
@Inject
BookmarkManager bookmarkManager;
@Inject
HistoryDatabase mHistoryDatabase;
@Inject
Bus eventBus;
@Inject
public BookmarksDialogBuilder() {
public LightningDialogBuilder() {
BrowserApp.getAppComponent().inject(this);
}
@ -46,7 +59,7 @@ public class BookmarksDialogBuilder { @@ -46,7 +59,7 @@ public class BookmarksDialogBuilder {
* @param context used to show the dialog
* @param url the long pressed url
*/
public void showLongPressedDialogForUrl(final Context context, final String url) {
public void showLongPressedDialogForBookmarkUrl(final Context context, final String url) {
final HistoryItem item;
if (url.startsWith(Constants.FILE) && url.endsWith(Constants.BOOKMARKS_FILENAME)) {
// TODO hacky, make a better bookmark mechanism in the future
@ -65,19 +78,19 @@ public class BookmarksDialogBuilder { @@ -65,19 +78,19 @@ public class BookmarksDialogBuilder {
if (item.isFolder()) {
showBookmarkFolderLongPressedDialog(context, item);
} else {
showLongPressedDialogForUrl(context, item);
showLongPressedDialogForBookmarkUrl(context, item);
}
}
}
public void showLongPressedDialogForUrl(final Context context, final HistoryItem item) {
public void showLongPressedDialogForBookmarkUrl(final Context context, final HistoryItem item) {
final DialogInterface.OnClickListener dialogClickListener =
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
eventBus.post(new BookmarkEvents.AsNewTab(item));
eventBus.post(new BrowserEvents.OpenUrlInNewTab(item.getUrl()));
break;
case DialogInterface.BUTTON_NEGATIVE:
if (bookmarkManager.deleteBookmark(item)) {
@ -197,4 +210,103 @@ public class BookmarksDialogBuilder { @@ -197,4 +210,103 @@ public class BookmarksDialogBuilder {
});
editFolderDialog.show();
}
public void showLongPressedHistoryLinkDialog(final Context context, final String url) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
eventBus.post(new BrowserEvents.OpenUrlInNewTab(url));
break;
case DialogInterface.BUTTON_NEGATIVE:
mHistoryDatabase.deleteHistoryItem(url);
// openHistory();
eventBus.post(new BrowserEvents.OpenUrlInCurrentTab(HistoryPage.getHistoryPage(context)));
break;
case DialogInterface.BUTTON_NEUTRAL:
eventBus.post(new BrowserEvents.OpenUrlInCurrentTab(url));
break;
default:
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.action_history)
.setMessage(R.string.dialog_history_long_press)
.setCancelable(true)
.setPositiveButton(R.string.action_new_tab, dialogClickListener)
.setNegativeButton(R.string.action_delete, dialogClickListener)
.setNeutralButton(R.string.action_open, dialogClickListener)
.show();
}
// TODO There should be a way in which we do not need an activity reference to dowload a file
public void showLongPressImageDialog(@NonNull final Activity activity, @NonNull final String url,
@NonNull final String userAgent) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
eventBus.post(new BrowserEvents.OpenUrlInNewTab(url));
break;
case DialogInterface.BUTTON_NEGATIVE:
eventBus.post(new BrowserEvents.OpenUrlInCurrentTab(url));
break;
case DialogInterface.BUTTON_NEUTRAL:
if (Build.VERSION.SDK_INT > 8) {
// Should be better to send an event on the bus here
Utils.downloadFile(activity, url,
userAgent, "attachment");
}
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(url.replace(Constants.HTTP, ""))
.setCancelable(true)
.setMessage(R.string.dialog_image)
.setPositiveButton(R.string.action_new_tab, dialogClickListener)
.setNegativeButton(R.string.action_open, dialogClickListener)
.setNeutralButton(R.string.action_download, dialogClickListener)
.show();
}
public void showLongPressLinkDialog(final Context context, final String url) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
eventBus.post(new BrowserEvents.OpenUrlInNewTab(url));
break;
case DialogInterface.BUTTON_NEGATIVE:
eventBus.post(new BrowserEvents.OpenUrlInCurrentTab(url));
break;
case DialogInterface.BUTTON_NEUTRAL:
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label", url);
clipboard.setPrimaryClip(clip);
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(context); // dialog
builder.setTitle(url)
.setCancelable(true)
.setMessage(R.string.dialog_link)
.setPositiveButton(R.string.action_new_tab, dialogClickListener)
.setNegativeButton(R.string.action_open, dialogClickListener)
.setNeutralButton(R.string.action_copy, dialogClickListener)
.show();
}
}

8
app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java

@ -42,7 +42,7 @@ import acr.browser.lightning.bus.BookmarkEvents; @@ -42,7 +42,7 @@ import acr.browser.lightning.bus.BookmarkEvents;
import acr.browser.lightning.bus.BrowserEvents;
import acr.browser.lightning.database.BookmarkManager;
import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.dialog.BookmarksDialogBuilder;
import acr.browser.lightning.dialog.LightningDialogBuilder;
import acr.browser.lightning.preference.PreferenceManager;
import acr.browser.lightning.utils.DownloadImageTask;
import acr.browser.lightning.utils.ThemeUtils;
@ -62,7 +62,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -62,7 +62,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
// Dialog builder
@Inject
BookmarksDialogBuilder bookmarksDialogBuilder;
LightningDialogBuilder bookmarksDialogBuilder;
@Inject
PreferenceManager preferenceManager;
@ -109,7 +109,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -109,7 +109,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(item.getTitle(), true),
true);
} else {
eventBus.post(new BookmarkEvents.Clicked(item));
eventBus.post(new BrowserEvents.OpenUrlInCurrentTab(item.getUrl()));
}
}
};
@ -293,7 +293,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -293,7 +293,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
if (item.isFolder()) {
bookmarksDialogBuilder.showBookmarkFolderLongPressedDialog(getContext(), item);
} else {
bookmarksDialogBuilder.showLongPressedDialogForUrl(getContext(), item);
bookmarksDialogBuilder.showLongPressLinkDialog(getContext(), item.getUrl());
}
}

19
app/src/main/java/acr/browser/lightning/object/SearchAdapter.java

@ -54,14 +54,11 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -54,14 +54,11 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
private final List<HistoryItem> mFilteredList = new ArrayList<>();
private final List<HistoryItem> mAllBookmarks = new ArrayList<>();
private final Object mLock = new Object();
private HistoryDatabase mDatabaseHandler;
private final Context mContext;
private boolean mUseGoogle = true;
private boolean mIsExecuting = false;
private final boolean mDarkTheme;
private final boolean mIncognito;
@Inject BookmarkManager mBookmarkManager;
@Inject PreferenceManager mPreferenceManager;
private static final String CACHE_FILE_TYPE = ".sgg";
private static final String ENCODING = "ISO-8859-1";
private static final long INTERVAL_DAY = 86400000;
@ -73,9 +70,17 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -73,9 +70,17 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
private final Drawable mHistoryDrawable;
private final Drawable mBookmarkDrawable;
@Inject
HistoryDatabase mDatabaseHandler;
@Inject
BookmarkManager mBookmarkManager;
@Inject
PreferenceManager mPreferenceManager;
public SearchAdapter(Context context, boolean dark, boolean incognito) {
BrowserApp.getAppComponent().inject(this);
mDatabaseHandler = HistoryDatabase.getInstance();
mAllBookmarks.addAll(mBookmarkManager.getAllBookmarks(true));
mUseGoogle = mPreferenceManager.getGoogleSearchSuggestionsEnabled();
mContext = context;
@ -125,7 +130,6 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -125,7 +130,6 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
mSuggestions.clear();
}
}
mDatabaseHandler = HistoryDatabase.getInstance();
}
public void refreshBookmarks() {
@ -240,13 +244,10 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -240,13 +244,10 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
mBookmarks.add(mAllBookmarks.get(n));
counter++;
}
}
}
}
if (mDatabaseHandler == null || mDatabaseHandler.isClosed()) {
mDatabaseHandler = HistoryDatabase.getInstance();
}
List<HistoryItem> historyList = mDatabaseHandler.findItemsContaining(constraint.toString());
synchronized (mHistory) {
mHistory.clear();

3
app/src/main/java/acr/browser/lightning/utils/WebUtils.java

@ -10,6 +10,7 @@ import android.webkit.WebStorage; @@ -10,6 +10,7 @@ import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewDatabase;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.database.HistoryDatabase;
/**
@ -32,7 +33,7 @@ public class WebUtils { @@ -32,7 +33,7 @@ public class WebUtils {
}
public static void clearHistory(@NonNull Context context) {
HistoryDatabase.getInstance().deleteHistory();
BrowserApp.getAppComponent().getHistoryDatabase().deleteHistory();
WebViewDatabase m = WebViewDatabase.getInstance(context);
m.clearFormData();
m.clearHttpAuthUsernamePassword();

234
app/src/main/java/acr/browser/lightning/view/LightningChromeClient.java

@ -0,0 +1,234 @@ @@ -0,0 +1,234 @@
package acr.browser.lightning.view;
import android.Manifest;
import android.app.Activity;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.View;
import android.webkit.GeolocationPermissions;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import com.squareup.otto.Bus;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import acr.browser.lightning.R;
import acr.browser.lightning.activity.BrowserActivity;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.bus.BrowserEvents;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.utils.PermissionsManager;
import acr.browser.lightning.utils.Utils;
/**
* @author Stefano Pacifici based on Anthony C. Restaino code
* @date 2015/09/21
*/
class LightningChromeClient extends WebChromeClient {
private static final String[] PERMISSIONS = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
private final BrowserActivity mActivity;
private final LightningView mLightningView;
private final Bus eventBus;
LightningChromeClient(BrowserActivity activity, LightningView lightningView) {
mActivity = activity;
mLightningView = lightningView;
eventBus = BrowserApp.getAppComponent().getBus();
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (mLightningView.isShown()) {
mActivity.updateProgress(newProgress);
}
}
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
if (icon == null)
return;
mLightningView.mTitle.setFavicon(icon);
eventBus.post(new BrowserEvents.TabsChanged()); ;
cacheFavicon(view.getUrl(), icon);
}
/**
* Naive caching of the favicon according to the domain name of the URL
* @param icon the icon to cache
*/
private void cacheFavicon(final String url, final Bitmap icon) {
if (icon == null) return;
final Uri uri = Uri.parse(url);
if (uri.getHost() == null) {
return;
}
new Thread(new Runnable() {
@Override
public void run() {
String hash = String.valueOf(uri.getHost().hashCode());
Log.d(Constants.TAG, "Caching icon for " + uri.getHost());
FileOutputStream fos = null;
try {
File image = new File(BrowserApp.getAppContext().getCacheDir(), hash + ".png");
fos = new FileOutputStream(image);
icon.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
Utils.close(fos);
}
}
}).start();
}
@Override
public void onReceivedTitle(WebView view, String title) {
if (title != null && !title.isEmpty()) {
mLightningView.mTitle.setTitle(title);
} else {
mLightningView.mTitle.setTitle(mActivity.getString(R.string.untitled));
}
eventBus.post(new BrowserEvents.TabsChanged());
if (view != null) {
mActivity.updateHistory(title, view.getUrl());
}
}
@Override
public void onGeolocationPermissionsShowPrompt(final String origin,
final GeolocationPermissions.Callback callback) {
PermissionsManager.getInstance().requestPermissionsIfNecessary(mActivity, PERMISSIONS);
final boolean remember = true;
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(mActivity.getString(R.string.location));
String org;
if (origin.length() > 50) {
org = origin.subSequence(0, 50) + "...";
} else {
org = origin;
}
builder.setMessage(org + mActivity.getString(R.string.message_location))
.setCancelable(true)
.setPositiveButton(mActivity.getString(R.string.action_allow),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
callback.invoke(origin, true, remember);
}
})
.setNegativeButton(mActivity.getString(R.string.action_dont_allow),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
callback.invoke(origin, false, remember);
}
});
AlertDialog alert = builder.create();
alert.show();
}
@Override
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture,
Message resultMsg) {
mActivity.onCreateWindow(resultMsg);
return true;
}
@Override
public void onCloseWindow(WebView window) {
mActivity.onCloseWindow(mLightningView);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
mActivity.openFileChooser(uploadMsg);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
mActivity.openFileChooser(uploadMsg);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
mActivity.openFileChooser(uploadMsg);
}
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
mActivity.showFileChooser(filePathCallback);
return true;
}
@Override
public Bitmap getDefaultVideoPoster() {
// TODO Simplify the method can be moved here
return mActivity.getDefaultVideoPoster();
}
@Override
public View getVideoLoadingProgressView() {
// TODO Simplify the method can be moved here
return mActivity.getVideoLoadingProgressView();
}
@Override
public void onHideCustomView() {
mActivity.onHideCustomView();
super.onHideCustomView();
}
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
// While these lines might look like they work, in practice,
// Full-screen videos won't work correctly. I may test this out some
// more
// if (view instanceof FrameLayout) {
// FrameLayout frame = (FrameLayout) view;
// if (frame.getFocusedChild() instanceof VideoView) {
// VideoView video = (VideoView) frame.getFocusedChild();
// video.stopPlayback();
// frame.removeView(video);
// video.setVisibility(View.GONE);
// }
// } else {
mActivity.onShowCustomView(view, callback);
// }
super.onShowCustomView(view, callback);
}
@Override
@Deprecated
public void onShowCustomView(View view, int requestedOrientation,
CustomViewCallback callback) {
// While these lines might look like they work, in practice,
// Full-screen videos won't work correctly. I may test this out some
// more
// if (view instanceof FrameLayout) {
// FrameLayout frame = (FrameLayout) view;
// if (frame.getFocusedChild() instanceof VideoView) {
// VideoView video = (VideoView) frame.getFocusedChild();
// video.stopPlayback();
// frame.removeView(video);
// video.setVisibility(View.GONE);
// }
// } else {
mActivity.onShowCustomView(view, callback);
// }
super.onShowCustomView(view, requestedOrientation, callback);
}
}

555
app/src/main/java/acr/browser/lightning/view/LightningView.java

@ -6,27 +6,18 @@ package acr.browser.lightning.view; @@ -6,27 +6,18 @@ package acr.browser.lightning.view;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.net.MailTo;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.text.InputType;
import android.text.method.PasswordTransformationMethod;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
@ -35,45 +26,30 @@ import android.view.View; @@ -35,45 +26,30 @@ import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
import android.webkit.CookieManager;
import android.webkit.GeolocationPermissions;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.webkit.WebSettings.PluginState;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.EditText;
import android.widget.LinearLayout;
import com.squareup.otto.Bus;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import javax.inject.Inject;
import acr.browser.lightning.R;
import acr.browser.lightning.activity.BrowserActivity;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.bus.BrowserEvents;
import acr.browser.lightning.bus.TabEvents;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.constant.HistoryPage;
import acr.browser.lightning.constant.StartPage;
import acr.browser.lightning.controller.BrowserController;
import acr.browser.lightning.dialog.BookmarksDialogBuilder;
import acr.browser.lightning.dialog.LightningDialogBuilder;
import acr.browser.lightning.download.LightningDownloadListener;
import acr.browser.lightning.preference.PreferenceManager;
import acr.browser.lightning.utils.AdBlock;
import acr.browser.lightning.utils.IntentUtils;
import acr.browser.lightning.utils.PermissionsManager;
import acr.browser.lightning.utils.ProxyUtils;
import acr.browser.lightning.utils.ThemeUtils;
@ -81,21 +57,15 @@ import acr.browser.lightning.utils.Utils; @@ -81,21 +57,15 @@ import acr.browser.lightning.utils.Utils;
public class LightningView {
private final Title mTitle;
final LightningViewTitle mTitle;
private WebView mWebView;
private final boolean mIsIncognitoTab;
private final BrowserController mBrowserController = null; // TODO REMOVE
final boolean mIsIncognitoTab;
private final GestureDetector mGestureDetector;
private final Activity mActivity;
private final BrowserActivity mActivity;
private static String mHomepage;
private static String mDefaultUserAgent;
// TODO fix so that mWebpageBitmap can be static - static changes the icon when switching from light to dark and then back to light
private final Bitmap mWebpageBitmap;
private final AdBlock mAdBlock;
private final IntentUtils mIntentUtils;
private final Paint mPaint = new Paint();
private boolean isForegroundTab;
private boolean mTextReflow = false;
private boolean mInvertPage = false;
private boolean mToggleDesktop = false;
private static float mMaxFling;
@ -118,23 +88,20 @@ public class LightningView { @@ -118,23 +88,20 @@ public class LightningView {
PreferenceManager mPreferences;
@Inject
BookmarksDialogBuilder bookmarksDialogBuilder;
LightningDialogBuilder bookmarksDialogBuilder;
@SuppressLint("NewApi")
public LightningView(Activity activity, String url, boolean darkTheme, boolean isIncognito) {
public LightningView(BrowserActivity activity, String url, boolean darkTheme, boolean isIncognito) {
BrowserApp.getAppComponent().inject(this);
mActivity = activity;
mWebView = new WebView(activity);
mIsIncognitoTab = isIncognito;
mTitle = new Title(activity, darkTheme);
mAdBlock = AdBlock.getInstance(activity.getApplicationContext());
mTitle = new LightningViewTitle(activity, darkTheme);
// mAdBlock = AdBlock.getInstance(activity.getApplicationContext());
mPermissionsManager = PermissionsManager.getInstance();
mWebpageBitmap = mTitle.mDefaultIcon;
mMaxFling = ViewConfiguration.get(activity).getScaledMaximumFlingVelocity();
mIntentUtils = new IntentUtils(activity);
mWebView.setDrawingCacheBackgroundColor(Color.WHITE);
mWebView.setFocusableInTouchMode(true);
mWebView.setFocusable(true);
@ -149,8 +116,8 @@ public class LightningView { @@ -149,8 +116,8 @@ public class LightningView {
mWebView.setScrollbarFadingEnabled(true);
mWebView.setSaveEnabled(true);
mWebView.setNetworkAvailable(true);
mWebView.setWebChromeClient(new LightningChromeClient(activity));
mWebView.setWebViewClient(new LightningWebClient(activity));
mWebView.setWebChromeClient(new LightningChromeClient(activity, this));
mWebView.setWebViewClient(new LightningWebClient(activity, this));
mWebView.setDownloadListener(new LightningDownloadListener(activity));
mGestureDetector = new GestureDetector(activity, new CustomGestureListener());
mWebView.setOnTouchListener(new TouchListener());
@ -224,7 +191,7 @@ public class LightningView { @@ -224,7 +191,7 @@ public class LightningView {
settings.setDefaultTextEncodingName(mPreferences.getTextEncoding());
mHomepage = mPreferences.getHomepage();
mAdBlock.updatePreference();
// mAdBlock.updatePreference();
setColorMode(mPreferences.getRenderingMode());
@ -275,7 +242,6 @@ public class LightningView { @@ -275,7 +242,6 @@ public class LightningView {
}
if (mPreferences.getTextReflowEnabled()) {
mTextReflow = true;
settings.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
if (API >= android.os.Build.VERSION_CODES.KITKAT) {
try {
@ -287,7 +253,6 @@ public class LightningView { @@ -287,7 +253,6 @@ public class LightningView {
}
}
} else {
mTextReflow = false;
settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
}
@ -549,36 +514,6 @@ public class LightningView { @@ -549,36 +514,6 @@ public class LightningView {
}
}
/**
* Naive caching of the favicon according to the domain name of the URL
* @param icon the icon to cache
*/
private void cacheFavicon(final Bitmap icon) {
if (icon == null) return;
final Uri uri = Uri.parse(getUrl());
if (uri.getHost() == null) {
return;
}
new Thread(new Runnable() {
@Override
public void run() {
String hash = String.valueOf(uri.getHost().hashCode());
Log.d(Constants.TAG, "Caching icon for " + uri.getHost());
FileOutputStream fos = null;
try {
File image = new File(BrowserApp.getAppContext().getCacheDir(), hash + ".png");
fos = new FileOutputStream(image);
icon.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
Utils.close(fos);
}
}
}).start();
}
@SuppressLint("NewApi")
public synchronized void find(String text) {
if (mWebView != null) {
@ -623,6 +558,14 @@ public class LightningView { @@ -623,6 +558,14 @@ public class LightningView {
}
}
/**
* Used by {@link LightningWebClient}
*
* @return true if the page is in inverted mode, false otherwise
*/
public boolean getInvertePage() {
return mInvertPage;
}
/**
* handles a long click on the page, parameter String url
* is the url that should have been obtained from the WebView touch node
@ -634,36 +577,36 @@ public class LightningView { @@ -634,36 +577,36 @@ public class LightningView {
if (currentUrl != null && currentUrl.startsWith(Constants.FILE)) {
if (currentUrl.endsWith(HistoryPage.FILENAME)) {
if (url != null) {
// TODO longPressHistoryLink(url);
bookmarksDialogBuilder.showLongPressedHistoryLinkDialog(mActivity, url);
} else if (result != null && result.getExtra() != null) {
final String newUrl = result.getExtra();
// TODO longPressHistoryLink(newUrl);
bookmarksDialogBuilder.showLongPressedHistoryLinkDialog(mActivity, newUrl);
}
} else if (currentUrl.endsWith(Constants.BOOKMARKS_FILENAME)) {
if (url != null) {
bookmarksDialogBuilder.showLongPressedDialogForUrl(mActivity, url);
bookmarksDialogBuilder.showLongPressLinkDialog(mActivity, url);
} else if (result != null && result.getExtra() != null) {
final String newUrl = result.getExtra();
bookmarksDialogBuilder.showLongPressedDialogForUrl(mActivity, newUrl);
bookmarksDialogBuilder.showLongPressLinkDialog(mActivity, newUrl);
}
}
} else {
if (url != null) {
if (result != null) {
if (result.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE || result.getType() == WebView.HitTestResult.IMAGE_TYPE) {
// TODO longPressImage(url);
bookmarksDialogBuilder.showLongPressImageDialog(mActivity, url, getUserAgent());
} else {
// TODO longPressLink(url);
bookmarksDialogBuilder.showLongPressLinkDialog(mActivity, url);
}
} else {
// TODO longPressLink(url);
bookmarksDialogBuilder.showLongPressLinkDialog(mActivity, url);
}
} else if (result != null && result.getExtra() != null) {
final String newUrl = result.getExtra();
if (result.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE || result.getType() == WebView.HitTestResult.IMAGE_TYPE) {
// TODO longPressImage(newUrl);
bookmarksDialogBuilder.showLongPressImageDialog(mActivity, newUrl, getUserAgent());
} else {
// TODO longPressLink(newUrl);
bookmarksDialogBuilder.showLongPressLinkDialog(mActivity, newUrl);
}
}
}
@ -716,438 +659,6 @@ public class LightningView { @@ -716,438 +659,6 @@ public class LightningView {
}
}
public class LightningWebClient extends WebViewClient {
final Activity mActivity;
LightningWebClient(Activity activity) {
mActivity = activity;
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (mAdBlock.isAd(request.getUrl().toString())) {
ByteArrayInputStream EMPTY = new ByteArrayInputStream("".getBytes());
return new WebResourceResponse("text/plain", "utf-8", EMPTY);
}
}
return super.shouldInterceptRequest(view, request);
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (mAdBlock.isAd(url)) {
ByteArrayInputStream EMPTY = new ByteArrayInputStream("".getBytes());
return new WebResourceResponse("text/plain", "utf-8", EMPTY);
}
return null;
}
@SuppressLint("NewApi")
@Override
public void onPageFinished(WebView view, String url) {
if (view.isShown()) {
mBrowserController.updateUrl(url, true);
view.postInvalidate();
}
if (view.getTitle() == null || view.getTitle().isEmpty()) {
mTitle.setTitle(mActivity.getString(R.string.untitled));
} else {
mTitle.setTitle(view.getTitle());
}
if (API >= android.os.Build.VERSION_CODES.KITKAT && mInvertPage) {
view.evaluateJavascript(Constants.JAVASCRIPT_INVERT_PAGE, null);
}
eventBus.post(new BrowserEvents.TabsChanged());
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
if (isShown()) {
mBrowserController.updateUrl(url, false);
mBrowserController.showActionBar();
}
mTitle.setFavicon(mWebpageBitmap);
eventBus.post(new BrowserEvents.TabsChanged());
}
@Override
public void onReceivedHttpAuthRequest(final WebView view, @NonNull final HttpAuthHandler handler,
final String host, final String realm) {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
final EditText name = new EditText(mActivity);
final EditText password = new EditText(mActivity);
LinearLayout passLayout = new LinearLayout(mActivity);
passLayout.setOrientation(LinearLayout.VERTICAL);
passLayout.addView(name);
passLayout.addView(password);
name.setHint(mActivity.getString(R.string.hint_username));
name.setSingleLine();
password.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
password.setSingleLine();
password.setTransformationMethod(new PasswordTransformationMethod());
password.setHint(mActivity.getString(R.string.hint_password));
builder.setTitle(mActivity.getString(R.string.title_sign_in));
builder.setView(passLayout);
builder.setCancelable(true)
.setPositiveButton(mActivity.getString(R.string.title_sign_in),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
String user = name.getText().toString();
String pass = password.getText().toString();
handler.proceed(user.trim(), pass.trim());
Log.d(Constants.TAG, "Request Login");
}
})
.setNegativeButton(mActivity.getString(R.string.action_cancel),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
handler.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private boolean mIsRunning = false;
private float mZoomScale = 0.0f;
@SuppressLint("NewApi")
@Override
public void onScaleChanged(final WebView view, final float oldScale, final float newScale) {
if (view.isShown() && mTextReflow && API >= android.os.Build.VERSION_CODES.KITKAT) {
if (mIsRunning)
return;
if (Math.abs(mZoomScale - newScale) > 0.01f) {
mIsRunning = view.postDelayed(new Runnable() {
@Override
public void run() {
mZoomScale = newScale;
view.evaluateJavascript(Constants.JAVASCRIPT_TEXT_REFLOW, null);
mIsRunning = false;
}
}, 100);
}
}
}
@Override
public void onReceivedSslError(WebView view, @NonNull final SslErrorHandler handler, SslError error) {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(mActivity.getString(R.string.title_warning));
builder.setMessage(mActivity.getString(R.string.message_untrusted_certificate))
.setCancelable(true)
.setPositiveButton(mActivity.getString(R.string.action_yes),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
handler.proceed();
}
})
.setNegativeButton(mActivity.getString(R.string.action_no),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
handler.cancel();
}
});
AlertDialog alert = builder.create();
if (error.getPrimaryError() == SslError.SSL_UNTRUSTED) {
alert.show();
} else {
handler.proceed();
}
}
@Override
public void onFormResubmission(WebView view, @NonNull final Message dontResend, final Message resend) {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(mActivity.getString(R.string.title_form_resubmission));
builder.setMessage(mActivity.getString(R.string.message_form_resubmission))
.setCancelable(true)
.setPositiveButton(mActivity.getString(R.string.action_yes),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
resend.sendToTarget();
}
})
.setNegativeButton(mActivity.getString(R.string.action_no),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dontResend.sendToTarget();
}
});
AlertDialog alert = builder.create();
alert.show();
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Check if configured proxy is available
if (!ProxyUtils.getInstance().isProxyReady()) {
// User has been notified
return true;
}
if (mIsIncognitoTab) {
return super.shouldOverrideUrlLoading(view, url);
}
if (url.startsWith("about:")) {
return super.shouldOverrideUrlLoading(view, url);
}
if (url.contains("mailto:")) {
MailTo mailTo = MailTo.parse(url);
Intent i = Utils.newEmailIntent(mailTo.getTo(), mailTo.getSubject(),
mailTo.getBody(), mailTo.getCc());
mActivity.startActivity(i);
view.reload();
return true;
} else if (url.startsWith("intent://")) {
Intent intent;
try {
intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
} catch (URISyntaxException ex) {
return false;
}
if (intent != null) {
try {
mActivity.startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.e(Constants.TAG, "ActivityNotFoundException");
}
return true;
}
}
return mIntentUtils.startActivityForUrl(mWebView, url);
}
}
public class LightningChromeClient extends WebChromeClient {
final Activity mActivity;
LightningChromeClient(Activity activity) {
mActivity = activity;
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (isShown()) {
mBrowserController.updateProgress(newProgress);
}
}
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
if (icon == null)
return;
mTitle.setFavicon(icon);
eventBus.post(new BrowserEvents.TabsChanged()); ;
cacheFavicon(icon);
}
@Override
public void onReceivedTitle(WebView view, String title) {
if (title != null && !title.isEmpty()) {
mTitle.setTitle(title);
} else {
mTitle.setTitle(mActivity.getString(R.string.untitled));
}
eventBus.post(new BrowserEvents.TabsChanged()); ;
if (view != null)
mBrowserController.updateHistory(title, view.getUrl());
}
@Override
public void onGeolocationPermissionsShowPrompt(final String origin,
final GeolocationPermissions.Callback callback) {
mPermissionsManager.requestPermissionsIfNecessary(mActivity, PERMISSIONS);
final boolean remember = true;
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(mActivity.getString(R.string.location));
String org;
if (origin.length() > 50) {
org = origin.subSequence(0, 50) + "...";
} else {
org = origin;
}
builder.setMessage(org + mActivity.getString(R.string.message_location))
.setCancelable(true)
.setPositiveButton(mActivity.getString(R.string.action_allow),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
callback.invoke(origin, true, remember);
}
})
.setNegativeButton(mActivity.getString(R.string.action_dont_allow),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
callback.invoke(origin, false, remember);
}
});
AlertDialog alert = builder.create();
alert.show();
}
@Override
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture,
Message resultMsg) {
mBrowserController.onCreateWindow(resultMsg);
return true;
}
@Override
public void onCloseWindow(WebView window) {
mBrowserController.onCloseWindow(LightningView.this);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
mBrowserController.openFileChooser(uploadMsg);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
mBrowserController.openFileChooser(uploadMsg);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
mBrowserController.openFileChooser(uploadMsg);
}
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
mBrowserController.showFileChooser(filePathCallback);
return true;
}
@Override
public Bitmap getDefaultVideoPoster() {
return mBrowserController.getDefaultVideoPoster();
}
@Override
public View getVideoLoadingProgressView() {
return mBrowserController.getVideoLoadingProgressView();
}
@Override
public void onHideCustomView() {
mBrowserController.onHideCustomView();
super.onHideCustomView();
}
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
// While these lines might look like they work, in practice,
// Full-screen videos won't work correctly. I may test this out some
// more
// if (view instanceof FrameLayout) {
// FrameLayout frame = (FrameLayout) view;
// if (frame.getFocusedChild() instanceof VideoView) {
// VideoView video = (VideoView) frame.getFocusedChild();
// video.stopPlayback();
// frame.removeView(video);
// video.setVisibility(View.GONE);
// }
// } else {
mBrowserController.onShowCustomView(view, callback);
// }
super.onShowCustomView(view, callback);
}
@Override
@Deprecated
public void onShowCustomView(View view, int requestedOrientation,
CustomViewCallback callback) {
// While these lines might look like they work, in practice,
// Full-screen videos won't work correctly. I may test this out some
// more
// if (view instanceof FrameLayout) {
// FrameLayout frame = (FrameLayout) view;
// if (frame.getFocusedChild() instanceof VideoView) {
// VideoView video = (VideoView) frame.getFocusedChild();
// video.stopPlayback();
// frame.removeView(video);
// video.setVisibility(View.GONE);
// }
// } else {
mBrowserController.onShowCustomView(view, callback);
// }
super.onShowCustomView(view, requestedOrientation, callback);
}
}
public class Title {
private Bitmap mFavicon;
private String mTitle;
private final Bitmap mDefaultIcon;
public Title(Context context, boolean darkTheme) {
mDefaultIcon = ThemeUtils.getThemedBitmap(context, R.drawable.ic_webpage, darkTheme);
mFavicon = mDefaultIcon;
mTitle = mActivity.getString(R.string.action_new_tab);
}
public void setFavicon(Bitmap favicon) {
if (favicon == null) {
mFavicon = mDefaultIcon;
} else {
mFavicon = Utils.padFavicon(favicon);
}
}
public void setTitle(String title) {
if (title == null) {
mTitle = "";
} else {
mTitle = title;
}
}
public void setTitleAndFavicon(String title, Bitmap favicon) {
mTitle = title;
if (favicon == null) {
mFavicon = mDefaultIcon;
} else {
mFavicon = Utils.padFavicon(favicon);
}
}
public String getTitle() {
return mTitle;
}
public Bitmap getFavicon() {
return mFavicon;
}
}
private class TouchListener implements OnTouchListener {
float mLocation;
@ -1170,9 +681,9 @@ public class LightningView { @@ -1170,9 +681,9 @@ public class LightningView {
} else if (mAction == MotionEvent.ACTION_UP) {
final float distance = (mY - mLocation);
if (distance > SCROLL_UP_THRESHOLD && view.getScrollY() < SCROLL_UP_THRESHOLD) {
mBrowserController.showActionBar();
mActivity.showActionBar();
} else if (distance < -SCROLL_UP_THRESHOLD) {
mBrowserController.hideActionBar();
mActivity.hideActionBar();
}
mLocation = 0;
}
@ -1187,9 +698,9 @@ public class LightningView { @@ -1187,9 +698,9 @@ public class LightningView {
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
int power = (int) (velocityY * 100 / mMaxFling);
if (power < -10) {
mBrowserController.hideActionBar();
mActivity.hideActionBar();
} else if (power > 15) {
mBrowserController.showActionBar();
mActivity.showActionBar();
}
return super.onFling(e1, e2, velocityX, velocityY);
}

66
app/src/main/java/acr/browser/lightning/view/LightningViewTitle.java

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
package acr.browser.lightning.view;
import android.content.Context;
import android.graphics.Bitmap;
import acr.browser.lightning.R;
import acr.browser.lightning.utils.ThemeUtils;
import acr.browser.lightning.utils.Utils;
/**
* @author Stefano Pacifici base on Anthony C. Restaino's code
* @date 2015/09/21
*/
class LightningViewTitle {
private static Bitmap DEFAULT_ICON = null;
private Bitmap mFavicon;
private String mTitle;
public LightningViewTitle(Context context, boolean darkTheme) {
if (DEFAULT_ICON == null) {
DEFAULT_ICON = ThemeUtils.getThemedBitmap(context, R.drawable.ic_webpage, darkTheme);
}
mFavicon = DEFAULT_ICON;
mTitle = context.getString(R.string.action_new_tab);
}
public void setFavicon(Bitmap favicon) {
if (favicon == null) {
mFavicon = DEFAULT_ICON;
} else {
mFavicon = Utils.padFavicon(favicon);
}
}
public void setTitle(String title) {
if (title == null) {
mTitle = "";
} else {
mTitle = title;
}
}
public void setTitleAndFavicon(String title, Bitmap favicon) {
mTitle = title;
if (favicon == null) {
mFavicon = DEFAULT_ICON;
} else {
mFavicon = Utils.padFavicon(favicon);
}
}
public String getTitle() {
return mTitle;
}
public Bitmap getFavicon() {
return mFavicon;
}
public Bitmap getDefaultIcon() {
return DEFAULT_ICON;
}
}

276
app/src/main/java/acr/browser/lightning/view/LightningWebClient.java

@ -0,0 +1,276 @@ @@ -0,0 +1,276 @@
package acr.browser.lightning.view;
import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.MailTo;
import android.net.http.SslError;
import android.os.Build;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.text.InputType;
import android.text.method.PasswordTransformationMethod;
import android.util.Log;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.EditText;
import android.widget.LinearLayout;
import com.squareup.otto.Bus;
import java.io.ByteArrayInputStream;
import java.net.URISyntaxException;
import acr.browser.lightning.R;
import acr.browser.lightning.activity.BrowserActivity;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.bus.BrowserEvents;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.utils.AdBlock;
import acr.browser.lightning.utils.IntentUtils;
import acr.browser.lightning.utils.ProxyUtils;
import acr.browser.lightning.utils.Utils;
/**
* @author Stefano Pacifici based on Anthony C. Restaino's code
* @date 2015/09/22
*/
public class LightningWebClient extends WebViewClient {
private final BrowserActivity mActivity;
private final LightningView mLightningView;
private final AdBlock mAdBlock;
private final Bus mEventBus;
private final IntentUtils mIntentUtils;
LightningWebClient(BrowserActivity activity, LightningView lightningView) {
mActivity = activity;
mLightningView = lightningView;
mAdBlock = AdBlock.getInstance(activity);
mAdBlock.updatePreference();
mEventBus = BrowserApp.getAppComponent().getBus();
mIntentUtils = new IntentUtils(activity);
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (mAdBlock.isAd(request.getUrl().toString())) {
ByteArrayInputStream EMPTY = new ByteArrayInputStream("".getBytes());
return new WebResourceResponse("text/plain", "utf-8", EMPTY);
}
}
return super.shouldInterceptRequest(view, request);
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (mAdBlock.isAd(url)) {
ByteArrayInputStream EMPTY = new ByteArrayInputStream("".getBytes());
return new WebResourceResponse("text/plain", "utf-8", EMPTY);
}
return null;
}
@SuppressLint("NewApi")
@Override
public void onPageFinished(WebView view, String url) {
if (view.isShown()) {
mActivity.updateUrl(url, true);
view.postInvalidate();
}
if (view.getTitle() == null || view.getTitle().isEmpty()) {
mLightningView.mTitle.setTitle(mActivity.getString(R.string.untitled));
} else {
mLightningView.mTitle.setTitle(view.getTitle());
}
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT &&
mLightningView.getInvertePage()) {
view.evaluateJavascript(Constants.JAVASCRIPT_INVERT_PAGE, null);
}
mEventBus.post(new BrowserEvents.TabsChanged());
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
if (mLightningView.isShown()) {
mActivity.updateUrl(url, false);
mActivity.showActionBar();
}
mEventBus.post(new BrowserEvents.TabsChanged());
}
@Override
public void onReceivedHttpAuthRequest(final WebView view, @NonNull final HttpAuthHandler handler,
final String host, final String realm) {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
final EditText name = new EditText(mActivity);
final EditText password = new EditText(mActivity);
LinearLayout passLayout = new LinearLayout(mActivity);
passLayout.setOrientation(LinearLayout.VERTICAL);
passLayout.addView(name);
passLayout.addView(password);
name.setHint(mActivity.getString(R.string.hint_username));
name.setSingleLine();
password.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
password.setSingleLine();
password.setTransformationMethod(new PasswordTransformationMethod());
password.setHint(mActivity.getString(R.string.hint_password));
builder.setTitle(mActivity.getString(R.string.title_sign_in));
builder.setView(passLayout);
builder.setCancelable(true)
.setPositiveButton(mActivity.getString(R.string.title_sign_in),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
String user = name.getText().toString();
String pass = password.getText().toString();
handler.proceed(user.trim(), pass.trim());
Log.d(Constants.TAG, "Request Login");
}
})
.setNegativeButton(mActivity.getString(R.string.action_cancel),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
handler.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private boolean mIsRunning = false;
private float mZoomScale = 0.0f;
@SuppressLint("NewApi")
@Override
public void onScaleChanged(final WebView view, final float oldScale, final float newScale) {
if (view.isShown() && mLightningView.mPreferences.getTextReflowEnabled() &&
Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
if (mIsRunning)
return;
if (Math.abs(mZoomScale - newScale) > 0.01f) {
mIsRunning = view.postDelayed(new Runnable() {
@Override
public void run() {
mZoomScale = newScale;
view.evaluateJavascript(Constants.JAVASCRIPT_TEXT_REFLOW, null);
mIsRunning = false;
}
}, 100);
}
}
}
@Override
public void onReceivedSslError(WebView view, @NonNull final SslErrorHandler handler, SslError error) {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(mActivity.getString(R.string.title_warning));
builder.setMessage(mActivity.getString(R.string.message_untrusted_certificate))
.setCancelable(true)
.setPositiveButton(mActivity.getString(R.string.action_yes),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
handler.proceed();
}
})
.setNegativeButton(mActivity.getString(R.string.action_no),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
handler.cancel();
}
});
AlertDialog alert = builder.create();
if (error.getPrimaryError() == SslError.SSL_UNTRUSTED) {
alert.show();
} else {
handler.proceed();
}
}
@Override
public void onFormResubmission(WebView view, @NonNull final Message dontResend, final Message resend) {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(mActivity.getString(R.string.title_form_resubmission));
builder.setMessage(mActivity.getString(R.string.message_form_resubmission))
.setCancelable(true)
.setPositiveButton(mActivity.getString(R.string.action_yes),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
resend.sendToTarget();
}
})
.setNegativeButton(mActivity.getString(R.string.action_no),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dontResend.sendToTarget();
}
});
AlertDialog alert = builder.create();
alert.show();
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Check if configured proxy is available
if (!ProxyUtils.getInstance().isProxyReady()) {
// User has been notified
return true;
}
if (mLightningView.mIsIncognitoTab) {
return super.shouldOverrideUrlLoading(view, url);
}
if (url.startsWith("about:")) {
return super.shouldOverrideUrlLoading(view, url);
}
if (url.contains("mailto:")) {
MailTo mailTo = MailTo.parse(url);
Intent i = Utils.newEmailIntent(mailTo.getTo(), mailTo.getSubject(),
mailTo.getBody(), mailTo.getCc());
mActivity.startActivity(i);
view.reload();
return true;
} else if (url.startsWith("intent://")) {
Intent intent;
try {
intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
} catch (URISyntaxException ex) {
return false;
}
if (intent != null) {
try {
mActivity.startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.e(Constants.TAG, "ActivityNotFoundException");
}
return true;
}
}
return mIntentUtils.startActivityForUrl(view, url);
}
}
Loading…
Cancel
Save