Browse Source

Moving to asynchronous consumption of the HistoryDatabase

master
anthony restaino 7 years ago
parent
commit
bed8163399
  1. 2
      app/build.gradle
  2. 192
      app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java
  3. 135
      app/src/main/java/acr/browser/lightning/activity/TabsManager.java
  4. 38
      app/src/main/java/acr/browser/lightning/app/BrowserApp.java
  5. 121
      app/src/main/java/acr/browser/lightning/constant/HistoryPage.java
  6. 70
      app/src/main/java/acr/browser/lightning/database/HistoryDatabase.java
  7. 84
      app/src/main/java/acr/browser/lightning/database/HistoryModel.java
  8. 350
      app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java
  9. 7
      app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java
  10. 63
      app/src/main/java/acr/browser/lightning/search/SuggestionsAdapter.java
  11. 10
      app/src/main/java/acr/browser/lightning/utils/WebUtils.java
  12. 4
      build.gradle

2
app/build.gradle

@ -99,7 +99,7 @@ dependencies { @@ -99,7 +99,7 @@ dependencies {
compile "info.guardianproject.netcipher:netcipher:$netcipherVersion"
compile "info.guardianproject.netcipher:netcipher-webkit:$netcipherVersion"
compile 'com.anthonycr.bonsai:bonsai:1.0'
compile 'com.anthonycr.bonsai:bonsai:1.1.0'
compile 'com.anthonycr.progress:animated-progress:1.0'

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

@ -13,7 +13,6 @@ import android.content.DialogInterface; @@ -13,7 +13,6 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PorterDuff;
@ -81,7 +80,9 @@ import android.widget.TextView.OnEditorActionListener; @@ -81,7 +80,9 @@ import android.widget.TextView.OnEditorActionListener;
import android.widget.VideoView;
import com.anthonycr.bonsai.Completable;
import com.anthonycr.bonsai.CompletableOnSubscribe;
import com.anthonycr.bonsai.Schedulers;
import com.anthonycr.bonsai.SingleOnSubscribe;
import com.anthonycr.grant.PermissionsManager;
import com.anthonycr.progress.AnimatedProgressBar;
import com.squareup.otto.Bus;
@ -105,8 +106,8 @@ import acr.browser.lightning.constant.Constants; @@ -105,8 +106,8 @@ import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.constant.HistoryPage;
import acr.browser.lightning.controller.UIController;
import acr.browser.lightning.database.BookmarkManager;
import acr.browser.lightning.database.HistoryDatabase;
import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.database.HistoryModel;
import acr.browser.lightning.dialog.BrowserDialog;
import acr.browser.lightning.dialog.LightningDialogBuilder;
import acr.browser.lightning.fragment.BookmarksFragment;
@ -115,6 +116,7 @@ import acr.browser.lightning.interpolator.BezierDecelerateInterpolator; @@ -115,6 +116,7 @@ import acr.browser.lightning.interpolator.BezierDecelerateInterpolator;
import acr.browser.lightning.receiver.NetworkReceiver;
import acr.browser.lightning.search.SuggestionsAdapter;
import acr.browser.lightning.utils.DrawableUtils;
import acr.browser.lightning.utils.Preconditions;
import acr.browser.lightning.utils.ProxyUtils;
import acr.browser.lightning.utils.ThemeUtils;
import acr.browser.lightning.utils.UrlUtils;
@ -197,8 +199,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -197,8 +199,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
private TabsManager mTabsManager;
@Inject HistoryDatabase mHistoryDatabase;
// Image
private Bitmap mWebpageBitmap;
private final ColorDrawable mBackground = new ColorDrawable();
@ -215,9 +215,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -215,9 +215,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
private static final int API = android.os.Build.VERSION.SDK_INT;
private static final String NETWORK_BROADCAST_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
private static final LayoutParams MATCH_PARENT = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
LayoutParams.MATCH_PARENT);
private static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
protected abstract boolean isIncognito();
@ -249,7 +249,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -249,7 +249,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mDarkTheme = mPreferences.getUseTheme() != 0 || isIncognito();
mIconColor = mDarkTheme ? ThemeUtils.getIconDarkThemeColor(this) : ThemeUtils.getIconLightThemeColor(this);
mDisabledIconColor = mDarkTheme ? ContextCompat.getColor(this, R.color.icon_dark_theme_disabled) :
ContextCompat.getColor(this, R.color.icon_light_theme_disabled);
ContextCompat.getColor(this, R.color.icon_light_theme_disabled);
mShowTabsInDrawer = mPreferences.getShowTabsInDrawer(!isTablet());
mSwapBookmarksAndTabs = mPreferences.getBookmarksAndTabsSwapped();
@ -307,10 +307,10 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -307,10 +307,10 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
final FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(getTabsFragmentViewId(), tabsFragment, TAG_TABS_FRAGMENT)
.replace(getBookmarksFragmentViewId(), bookmarksFragment, TAG_BOOKMARK_FRAGMENT)
.commit();
.beginTransaction()
.replace(getTabsFragmentViewId(), tabsFragment, TAG_TABS_FRAGMENT)
.replace(getBookmarksFragmentViewId(), bookmarksFragment, TAG_BOOKMARK_FRAGMENT)
.commit();
if (mShowTabsInDrawer) {
mToolbarLayout.removeView(findViewById(R.id.tabs_toolbar_container));
}
@ -432,7 +432,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -432,7 +432,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
private class SearchListenerClass implements OnKeyListener, OnEditorActionListener,
OnFocusChangeListener, OnTouchListener, SearchView.PreFocusListener {
OnFocusChangeListener, OnTouchListener, SearchView.PreFocusListener {
@Override
public boolean onKey(View searchView, int keyCode, KeyEvent keyEvent) {
@ -458,10 +458,10 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -458,10 +458,10 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
// hide the keyboard and search the web when the enter key
// button is pressed
if (actionId == EditorInfo.IME_ACTION_GO || actionId == EditorInfo.IME_ACTION_DONE
|| actionId == EditorInfo.IME_ACTION_NEXT
|| actionId == EditorInfo.IME_ACTION_SEND
|| actionId == EditorInfo.IME_ACTION_SEARCH
|| (arg2.getAction() == KeyEvent.KEYCODE_ENTER)) {
|| actionId == EditorInfo.IME_ACTION_NEXT
|| actionId == EditorInfo.IME_ACTION_SEND
|| actionId == EditorInfo.IME_ACTION_SEARCH
|| (arg2.getAction() == KeyEvent.KEYCODE_ENTER)) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearch.getWindowToken(), 0);
searchTheWeb(mSearch.getText().toString());
@ -498,7 +498,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -498,7 +498,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
public boolean onTouch(View v, MotionEvent event) {
if (mSearch.getCompoundDrawables()[2] != null) {
boolean tappedX = event.getX() > (mSearch.getWidth()
- mSearch.getPaddingRight() - mIcon.getIntrinsicWidth());
- mSearch.getPaddingRight() - mIcon.getIntrinsicWidth());
if (tappedX) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (mSearch.hasFocus()) {
@ -566,23 +566,23 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -566,23 +566,23 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
if (width > maxWidth) {
DrawerLayout.LayoutParams params = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawerLeft
.getLayoutParams();
.getLayoutParams();
params.width = maxWidth;
mDrawerLeft.setLayoutParams(params);
mDrawerLeft.requestLayout();
DrawerLayout.LayoutParams paramsRight = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawerRight
.getLayoutParams();
.getLayoutParams();
paramsRight.width = maxWidth;
mDrawerRight.setLayoutParams(paramsRight);
mDrawerRight.requestLayout();
} else {
DrawerLayout.LayoutParams params = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawerLeft
.getLayoutParams();
.getLayoutParams();
params.width = width;
mDrawerLeft.setLayoutParams(params);
mDrawerLeft.requestLayout();
DrawerLayout.LayoutParams paramsRight = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawerRight
.getLayoutParams();
.getLayoutParams();
paramsRight.width = width;
mDrawerRight.setLayoutParams(paramsRight);
mDrawerRight.requestLayout();
@ -622,7 +622,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -622,7 +622,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
case 0:
mSearchText = mPreferences.getSearchUrl();
if (!mSearchText.startsWith(Constants.HTTP)
&& !mSearchText.startsWith(Constants.HTTPS)) {
&& !mSearchText.startsWith(Constants.HTTPS)) {
mSearchText = Constants.GOOGLE_SEARCH;
}
break;
@ -676,8 +676,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -676,8 +676,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
searchTheWeb(mSearch.getText().toString());
}
} else if ((keyCode == KeyEvent.KEYCODE_MENU)
&& (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN)
&& (Build.MANUFACTURER.compareTo("LGE") == 0)) {
&& (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN)
&& (Build.MANUFACTURER.compareTo("LGE") == 0)) {
// Workaround for stupid LG devices that crash
return true;
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
@ -698,8 +698,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -698,8 +698,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
@Override
public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_MENU)
&& (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN)
&& (Build.MANUFACTURER.compareTo("LGE") == 0)) {
&& (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN)
&& (Build.MANUFACTURER.compareTo("LGE") == 0)) {
// Workaround for stupid LG devices that crash
openOptionsMenu();
return true;
@ -796,8 +796,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -796,8 +796,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
// By using a manager, adds a bookmark and notifies third parties about that
private void addBookmark(final String title, final String url) {
final HistoryItem item = !mBookmarkManager.isBookmark(url)
? new HistoryItem(url, title)
: null;
? new HistoryItem(url, title)
: null;
if (item != null && mBookmarkManager.addBookmark(item)) {
mSuggestionsAdapter.refreshBookmarks();
mBookmarksView.handleUpdatedUrl(url);
@ -806,8 +806,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -806,8 +806,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
private void deleteBookmark(final String title, final String url) {
final HistoryItem item = mBookmarkManager.isBookmark(url)
? new HistoryItem(url, title)
: null;
? new HistoryItem(url, title)
: null;
if (item != null && mBookmarkManager.deleteBookmark(item)) {
mSuggestionsAdapter.refreshBookmarks();
mBookmarksView.handleUpdatedUrl(url);
@ -852,17 +852,17 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -852,17 +852,17 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
*/
private void findInPage() {
BrowserDialog.showEditText(this,
R.string.action_find,
R.string.search_hint,
R.string.search_hint, new BrowserDialog.EditorListener() {
@Override
public void onClick(String text) {
if (!TextUtils.isEmpty(text)) {
mPresenter.findInPage(text);
showFindInPageControls(text);
R.string.action_find,
R.string.search_hint,
R.string.search_hint, new BrowserDialog.EditorListener() {
@Override
public void onClick(String text) {
if (!TextUtils.isEmpty(text)) {
mPresenter.findInPage(text);
showFindInPageControls(text);
}
}
}
});
});
}
private void showFindInPageControls(@NonNull String text) {
@ -892,24 +892,24 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -892,24 +892,24 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
return;
}
BrowserDialog.show(this, R.string.dialog_title_close_browser,
new BrowserDialog.Item(R.string.close_tab) {
@Override
public void onClick() {
mPresenter.deleteTab(position);
}
},
new BrowserDialog.Item(R.string.close_other_tabs) {
@Override
public void onClick() {
mPresenter.closeAllOtherTabs();
}
},
new BrowserDialog.Item(R.string.close_all_tabs) {
@Override
public void onClick() {
closeBrowser();
}
});
new BrowserDialog.Item(R.string.close_tab) {
@Override
public void onClick() {
mPresenter.deleteTab(position);
}
},
new BrowserDialog.Item(R.string.close_other_tabs) {
@Override
public void onClick() {
mPresenter.closeAllOtherTabs();
}
},
new BrowserDialog.Item(R.string.close_all_tabs) {
@Override
public void onClick() {
closeBrowser();
}
});
}
@Override
@ -1016,11 +1016,11 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1016,11 +1016,11 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
public void showBlockedLocalFileDialog(DialogInterface.OnClickListener listener) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
Dialog dialog = builder.setCancelable(true)
.setTitle(R.string.title_warning)
.setMessage(R.string.message_blocked_local)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.action_open, listener)
.show();
.setTitle(R.string.title_warning)
.setMessage(R.string.message_blocked_local)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.action_open, listener)
.show();
BrowserDialog.setDialogSize(this, dialog);
}
@ -1139,7 +1139,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1139,7 +1139,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
Log.d(TAG, "Cache Cleared");
}
if (mPreferences.getClearHistoryExitEnabled() && !isIncognito()) {
WebUtils.clearHistory(this, mHistoryDatabase);
WebUtils.clearHistory(this);
Log.d(TAG, "History Cleared");
}
if (mPreferences.getClearCookiesExitEnabled() && !isIncognito()) {
@ -1280,11 +1280,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1280,11 +1280,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mPresenter.shutdown();
if (mHistoryDatabase != null) {
mHistoryDatabase.close();
mHistoryDatabase = null;
}
super.onDestroy();
}
@ -1402,7 +1397,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1402,7 +1397,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mCurrentUiColor = color;
mToolbarLayout.setBackgroundColor(color);
mSearchBackground.getBackground().setColorFilter(DrawableUtils.mixColor(interpolatedTime,
startSearchColor, finalSearchColor), PorterDuff.Mode.SRC_IN);
startSearchColor, finalSearchColor), PorterDuff.Mode.SRC_IN);
}
};
animation.setDuration(300);
@ -1467,7 +1462,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1467,7 +1462,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
public void updateTabNumber(int number) {
if (mArrowImage != null && mShowTabsInDrawer) {
mArrowImage.setImageBitmap(DrawableUtils.getRoundedNumberImage(number, Utils.dpToPx(24),
Utils.dpToPx(24), ThemeUtils.getIconThemeColor(this, mDarkTheme), Utils.dpToPx(2.5f)));
Utils.dpToPx(24), ThemeUtils.getIconThemeColor(this, mDarkTheme), Utils.dpToPx(2.5f)));
}
}
@ -1481,20 +1476,15 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1481,20 +1476,15 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (UrlUtils.isSpecialUrl(url)) {
return;
}
BrowserApp.getIOThread().execute(new Runnable() {
@Override
public void run() {
try {
mHistoryDatabase.visitHistoryItem(url, title);
} catch (IllegalStateException e) {
Log.e(TAG, "IllegalStateException in updateHistory", e);
} catch (NullPointerException e) {
Log.e(TAG, "NullPointerException in updateHistory", e);
} catch (SQLiteException e) {
Log.e(TAG, "SQLiteException in updateHistory", e);
}
}
});
HistoryModel.visitHistoryItem(url, title)
.subscribeOn(Schedulers.io())
.subscribe(new CompletableOnSubscribe() {
@Override
public void onError(@NonNull Throwable throwable) {
Log.e(TAG, "Exception while updating history", throwable);
}
});
}
/**
@ -1543,7 +1533,19 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1543,7 +1533,19 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
* function that opens the HTML history page in the browser
*/
private void openHistory() {
new HistoryPage(mTabsManager.getCurrentTab(), getApplication(), mHistoryDatabase).load();
HistoryPage.getHistoryPage()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.main())
.subscribe(new SingleOnSubscribe<String>() {
@Override
public void onItem(@Nullable String item) {
Preconditions.checkNonNull(item);
LightningView view = mTabsManager.getCurrentTab();
if (view != null) {
view.loadUrl(item);
}
}
});
}
private View getBookmarkDrawer() {
@ -1855,7 +1857,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1855,7 +1857,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
private class VideoCompletionListener implements MediaPlayer.OnCompletionListener,
MediaPlayer.OnErrorListener {
MediaPlayer.OnErrorListener {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
@ -1928,16 +1930,16 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1928,16 +1930,16 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (enabled) {
if (immersive) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
@ -2190,7 +2192,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -2190,7 +2192,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
@Subscribe
public void loadHistory(final BrowserEvents.OpenHistoryInCurrentTab event) {
new HistoryPage(mTabsManager.getCurrentTab(), getApplication(), mHistoryDatabase).load();
openHistory();
}
/**
@ -2239,7 +2241,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -2239,7 +2241,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
private void handleBookmarksChange() {
final LightningView currentTab = mTabsManager.getCurrentTab();
if (currentTab != null && currentTab.getUrl().startsWith(Constants.FILE)
&& currentTab.getUrl().endsWith(BookmarkPage.FILENAME)) {
&& currentTab.getUrl().endsWith(BookmarkPage.FILENAME)) {
currentTab.loadBookmarkpage();
}
if (currentTab != null) {

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

@ -17,10 +17,7 @@ import android.webkit.WebView; @@ -17,10 +17,7 @@ import android.webkit.WebView;
import com.anthonycr.bonsai.Completable;
import com.anthonycr.bonsai.CompletableAction;
import com.anthonycr.bonsai.CompletableSubscriber;
import com.anthonycr.bonsai.Single;
import com.anthonycr.bonsai.SingleAction;
import com.anthonycr.bonsai.SingleOnSubscribe;
import com.anthonycr.bonsai.SingleSubscriber;
import com.anthonycr.bonsai.Stream;
import com.anthonycr.bonsai.StreamAction;
import com.anthonycr.bonsai.StreamOnSubscribe;
@ -39,13 +36,13 @@ import acr.browser.lightning.constant.Constants; @@ -39,13 +36,13 @@ import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.constant.HistoryPage;
import acr.browser.lightning.constant.StartPage;
import acr.browser.lightning.database.BookmarkManager;
import acr.browser.lightning.database.HistoryDatabase;
import acr.browser.lightning.dialog.BrowserDialog;
import acr.browser.lightning.preference.PreferenceManager;
import com.anthonycr.bonsai.Schedulers;
import acr.browser.lightning.utils.FileUtils;
import acr.browser.lightning.utils.Preconditions;
import acr.browser.lightning.utils.UrlUtils;
import acr.browser.lightning.view.LightningView;
@ -70,7 +67,6 @@ public class TabsManager { @@ -70,7 +67,6 @@ public class TabsManager {
@Inject PreferenceManager mPreferenceManager;
@Inject BookmarkManager mBookmarkManager;
@Inject HistoryDatabase mHistoryManager;
@Inject Bus mEventBus;
@Inject Application mApp;
@ -116,8 +112,8 @@ public class TabsManager { @@ -116,8 +112,8 @@ public class TabsManager {
* @param incognito whether or not we are in incognito mode.
*/
public synchronized Completable initializeTabs(@NonNull final Activity activity,
@Nullable final Intent intent,
final boolean incognito) {
@Nullable final Intent intent,
final boolean incognito) {
return Completable.create(new CompletableAction() {
@Override
public void onSubscribe(@NonNull CompletableSubscriber subscriber) {
@ -158,68 +154,79 @@ public class TabsManager { @@ -158,68 +154,79 @@ public class TabsManager {
private void restoreLostTabs(@Nullable final String url, @NonNull final Activity activity,
@NonNull final CompletableSubscriber subscriber) {
restoreState().subscribeOn(Schedulers.io())
.observeOn(Schedulers.main()).subscribe(new StreamOnSubscribe<Bundle>() {
@Override
public void onNext(@Nullable Bundle item) {
LightningView tab = newTab(activity, "", false);
String url = item.getString(URL_KEY);
if (url != null && tab.getWebView() != null) {
if (UrlUtils.isBookmarkUrl(url)) {
new BookmarkPage(tab, activity, mBookmarkManager).load();
} else if (UrlUtils.isStartPageUrl(url)) {
new StartPage(tab, mApp).load();
} else if (UrlUtils.isHistoryUrl(url)) {
new HistoryPage(tab, mApp, mHistoryManager).load();
restoreState()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.main())
.subscribe(new StreamOnSubscribe<Bundle>() {
@Override
public void onNext(@Nullable Bundle item) {
final LightningView tab = newTab(activity, "", false);
String url = item.getString(URL_KEY);
if (url != null && tab.getWebView() != null) {
if (UrlUtils.isBookmarkUrl(url)) {
new BookmarkPage(tab, activity, mBookmarkManager).load();
} else if (UrlUtils.isStartPageUrl(url)) {
new StartPage(tab, mApp).load();
} else if (UrlUtils.isHistoryUrl(url)) {
HistoryPage.getHistoryPage()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.main())
.subscribe(new SingleOnSubscribe<String>() {
@Override
public void onItem(@Nullable String item) {
Preconditions.checkNonNull(item);
tab.loadUrl(item);
}
});
}
} else if (tab.getWebView() != null) {
tab.getWebView().restoreState(item);
}
}
} else if (tab.getWebView() != null) {
tab.getWebView().restoreState(item);
}
}
@Override
public void onComplete() {
if (url != null) {
if (url.startsWith(Constants.FILE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
Dialog dialog = builder.setCancelable(true)
.setTitle(R.string.title_warning)
.setMessage(R.string.message_blocked_local)
.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
if (mTabList.isEmpty()) {
newTab(activity, null, false);
}
finishInitialization();
subscriber.onComplete();
}
})
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.action_open, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
newTab(activity, url, false);
@Override
public void onComplete() {
if (url != null) {
if (url.startsWith(Constants.FILE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
Dialog dialog = builder.setCancelable(true)
.setTitle(R.string.title_warning)
.setMessage(R.string.message_blocked_local)
.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
if (mTabList.isEmpty()) {
newTab(activity, null, false);
}
finishInitialization();
subscriber.onComplete();
}
})
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.action_open, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
newTab(activity, url, false);
}
}).show();
BrowserDialog.setDialogSize(activity, dialog);
} else {
newTab(activity, url, false);
if (mTabList.isEmpty()) {
newTab(activity, null, false);
}
}).show();
BrowserDialog.setDialogSize(activity, dialog);
} else {
newTab(activity, url, false);
if (mTabList.isEmpty()) {
newTab(activity, null, false);
finishInitialization();
subscriber.onComplete();
}
} else {
if (mTabList.isEmpty()) {
newTab(activity, null, false);
}
finishInitialization();
subscriber.onComplete();
}
finishInitialization();
subscriber.onComplete();
}
} else {
if (mTabList.isEmpty()) {
newTab(activity, null, false);
}
finishInitialization();
subscriber.onComplete();
}
}
});
});
}
/**

38
app/src/main/java/acr/browser/lightning/app/BrowserApp.java

@ -8,6 +8,7 @@ import android.content.Context; @@ -8,6 +8,7 @@ import android.content.Context;
import android.os.Build;
import android.os.StrictMode;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.webkit.WebView;
@ -23,30 +24,38 @@ import acr.browser.lightning.BuildConfig; @@ -23,30 +24,38 @@ import acr.browser.lightning.BuildConfig;
import acr.browser.lightning.preference.PreferenceManager;
import acr.browser.lightning.utils.FileUtils;
import acr.browser.lightning.utils.MemoryLeakUtils;
import acr.browser.lightning.utils.Preconditions;
public class BrowserApp extends Application {
private static final String TAG = BrowserApp.class.getSimpleName();
private static AppComponent mAppComponent;
@Nullable private static Application sApplication;
@Nullable private static AppComponent sAppComponent;
private static final Executor mIOThread = Executors.newSingleThreadExecutor();
private static final Executor mTaskThread = Executors.newCachedThreadPool();
@Inject Bus mBus;
@Inject PreferenceManager mPreferenceManager;
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
sApplication = this;
}
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
.detectAll()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
.detectAll()
.penaltyLog()
.build());
}
final Thread.UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
@ -67,8 +76,8 @@ public class BrowserApp extends Application { @@ -67,8 +76,8 @@ public class BrowserApp extends Application {
}
});
mAppComponent = DaggerAppComponent.builder().appModule(new AppModule(this)).build();
mAppComponent.inject(this);
sAppComponent = DaggerAppComponent.builder().appModule(new AppModule(this)).build();
sAppComponent.inject(this);
if (mPreferenceManager.getUseLeakCanary() && !isRelease()) {
LeakCanary.install(this);
@ -86,13 +95,21 @@ public class BrowserApp extends Application { @@ -86,13 +95,21 @@ public class BrowserApp extends Application {
});
}
@NonNull
public static Application getApplication() {
Preconditions.checkNonNull(sApplication);
return sApplication;
}
@NonNull
public static BrowserApp get(@NonNull Context context) {
return (BrowserApp) context.getApplicationContext();
}
@NonNull
public static AppComponent getAppComponent() {
return mAppComponent;
Preconditions.checkNonNull(sAppComponent);
return sAppComponent;
}
@NonNull
@ -105,6 +122,7 @@ public class BrowserApp extends Application { @@ -105,6 +122,7 @@ public class BrowserApp extends Application {
return mTaskThread;
}
@NonNull
public static Bus getBus(@NonNull Context context) {
return get(context).mBus;
}

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

@ -4,26 +4,29 @@ @@ -4,26 +4,29 @@
package acr.browser.lightning.constant;
import android.app.Application;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import com.anthonycr.bonsai.Single;
import com.anthonycr.bonsai.SingleAction;
import com.anthonycr.bonsai.SingleOnSubscribe;
import com.anthonycr.bonsai.SingleSubscriber;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.List;
import acr.browser.lightning.R;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.database.HistoryDatabase;
import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.database.HistoryModel;
import acr.browser.lightning.utils.Preconditions;
import acr.browser.lightning.utils.Utils;
import acr.browser.lightning.view.LightningView;
public class HistoryPage extends AsyncTask<Void, Void, Void> {
public class HistoryPage {
private static final String TAG = HistoryPage.class.getSimpleName();
@ -43,70 +46,54 @@ public class HistoryPage extends AsyncTask<Void, Void, Void> { @@ -43,70 +46,54 @@ public class HistoryPage extends AsyncTask<Void, Void, Void> {
private static final String END = "</div></body></html>";
@NonNull private final WeakReference<LightningView> mTabReference;
@NonNull private final Application mApp;
@NonNull private final String mTitle;
private final HistoryDatabase mHistoryDatabase;
@Nullable private String mHistoryUrl = null;
public HistoryPage(LightningView tab, @NonNull Application app, HistoryDatabase database) {
mTabReference = new WeakReference<>(tab);
mApp = app;
mTitle = app.getString(R.string.action_history);
mHistoryDatabase = database;
}
@Nullable
@Override
protected Void doInBackground(Void... params) {
mHistoryUrl = getHistoryPage();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
LightningView tab = mTabReference.get();
if (tab != null && mHistoryUrl != null) {
tab.loadUrl(mHistoryUrl);
}
}
private HistoryPage() {}
@NonNull
private String getHistoryPage() {
StringBuilder historyBuilder = new StringBuilder(HEADING_1 + mTitle + HEADING_2);
List<HistoryItem> historyList = mHistoryDatabase.getLastHundredItems();
Iterator<HistoryItem> it = historyList.iterator();
HistoryItem helper;
while (it.hasNext()) {
helper = it.next();
historyBuilder.append(PART1);
historyBuilder.append(helper.getUrl());
historyBuilder.append(PART2);
historyBuilder.append(helper.getTitle());
historyBuilder.append(PART3);
historyBuilder.append(helper.getUrl());
historyBuilder.append(PART4);
}
historyBuilder.append(END);
File historyWebPage = new File(mApp.getFilesDir(), FILENAME);
FileWriter historyWriter = null;
try {
//noinspection IOResourceOpenedButNotSafelyClosed
historyWriter = new FileWriter(historyWebPage, false);
historyWriter.write(historyBuilder.toString());
} catch (IOException e) {
Log.e(TAG, "Unable to write history page to disk", e);
} finally {
Utils.close(historyWriter);
}
return Constants.FILE + historyWebPage;
}
public void load() {
executeOnExecutor(BrowserApp.getIOThread());
public static Single<String> getHistoryPage() {
return Single.create(new SingleAction<String>() {
@Override
public void onSubscribe(@NonNull final SingleSubscriber<String> subscriber) {
final String title = BrowserApp.getApplication().getString(R.string.action_history);
final StringBuilder historyBuilder = new StringBuilder(HEADING_1 + title + HEADING_2);
HistoryModel.lastHundredVisitedHistoryItems()
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
@Override
public void onItem(@Nullable List<HistoryItem> item) {
Preconditions.checkNonNull(item);
Iterator<HistoryItem> it = item.iterator();
HistoryItem helper;
while (it.hasNext()) {
helper = it.next();
historyBuilder.append(PART1);
historyBuilder.append(helper.getUrl());
historyBuilder.append(PART2);
historyBuilder.append(helper.getTitle());
historyBuilder.append(PART3);
historyBuilder.append(helper.getUrl());
historyBuilder.append(PART4);
}
historyBuilder.append(END);
File historyWebPage = new File(BrowserApp.getApplication().getFilesDir(), FILENAME);
FileWriter historyWriter = null;
try {
//noinspection IOResourceOpenedButNotSafelyClosed
historyWriter = new FileWriter(historyWebPage, false);
historyWriter.write(historyBuilder.toString());
} catch (IOException e) {
Log.e(TAG, "Unable to write history page to disk", e);
} finally {
Utils.close(historyWriter);
}
subscriber.onItem(Constants.FILE + historyWebPage);
subscriber.onComplete();
}
});
}
});
}
/**

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

@ -4,7 +4,6 @@ @@ -4,7 +4,6 @@
package acr.browser.lightning.database;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
@ -16,15 +15,11 @@ import android.support.annotation.WorkerThread; @@ -16,15 +15,11 @@ import android.support.annotation.WorkerThread;
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;
@SuppressWarnings("unused")
@WorkerThread
@Singleton
public class HistoryDatabase extends SQLiteOpenHelper {
class HistoryDatabase extends SQLiteOpenHelper {
// All Static variables
// Database Version
@ -42,15 +37,24 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -42,15 +37,24 @@ public class HistoryDatabase extends SQLiteOpenHelper {
private static final String KEY_TITLE = "title";
private static final String KEY_TIME_VISITED = "time";
@Nullable
private SQLiteDatabase mDatabase;
@Nullable private SQLiteDatabase mDatabase;
@Nullable private static HistoryDatabase sInstance;
@Inject
public HistoryDatabase(@NonNull Context context) {
super(context.getApplicationContext(), DATABASE_NAME, null, DATABASE_VERSION);
private HistoryDatabase() {
super(BrowserApp.getApplication(), DATABASE_NAME, null, DATABASE_VERSION);
mDatabase = HistoryDatabase.this.getWritableDatabase();
}
@NonNull
public synchronized static HistoryDatabase getInstance() {
if (sInstance == null) {
sInstance = new HistoryDatabase();
}
return sInstance;
}
// Creating Tables
@Override
public void onCreate(@NonNull SQLiteDatabase db) {
@ -78,6 +82,16 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -78,6 +82,16 @@ public class HistoryDatabase extends SQLiteOpenHelper {
super.close();
}
@NonNull
private static HistoryItem fromCursor(@NonNull Cursor cursor) {
HistoryItem historyItem = new HistoryItem();
historyItem.setUrl(cursor.getString(1));
historyItem.setTitle(cursor.getString(2));
historyItem.setImageId(R.drawable.ic_history);
return historyItem;
}
@WorkerThread
@NonNull
private SQLiteDatabase openIfNecessary() {
@ -88,7 +102,7 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -88,7 +102,7 @@ public class HistoryDatabase extends SQLiteOpenHelper {
}
@WorkerThread
public synchronized void deleteHistory() {
synchronized void deleteHistory() {
mDatabase = openIfNecessary();
mDatabase.delete(TABLE_HISTORY, null, null);
mDatabase.close();
@ -96,13 +110,13 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -96,13 +110,13 @@ public class HistoryDatabase extends SQLiteOpenHelper {
}
@WorkerThread
public synchronized void deleteHistoryItem(@NonNull String url) {
synchronized void deleteHistoryItem(@NonNull String url) {
mDatabase = openIfNecessary();
mDatabase.delete(TABLE_HISTORY, KEY_URL + " = ?", new String[]{url});
}
@WorkerThread
public synchronized void visitHistoryItem(@NonNull String url, @Nullable String title) {
synchronized void visitHistoryItem(@NonNull String url, @Nullable String title) {
mDatabase = openIfNecessary();
ContentValues values = new ContentValues();
values.put(KEY_TITLE, title == null ? "" : title);
@ -148,7 +162,7 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -148,7 +162,7 @@ public class HistoryDatabase extends SQLiteOpenHelper {
@WorkerThread
@NonNull
public synchronized List<HistoryItem> findItemsContaining(@Nullable String search) {
synchronized List<HistoryItem> findItemsContaining(@Nullable String search) {
mDatabase = openIfNecessary();
List<HistoryItem> itemList = new ArrayList<>(5);
if (search == null) {
@ -161,11 +175,7 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -161,11 +175,7 @@ public class HistoryDatabase extends SQLiteOpenHelper {
new String[]{search, search}, null, null, KEY_TIME_VISITED + " DESC", "5");
while (cursor.moveToNext()) {
HistoryItem item = new HistoryItem();
item.setUrl(cursor.getString(1));
item.setTitle(cursor.getString(2));
item.setImageId(R.drawable.ic_history);
itemList.add(item);
itemList.add(fromCursor(cursor));
}
cursor.close();
@ -175,17 +185,13 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -175,17 +185,13 @@ public class HistoryDatabase extends SQLiteOpenHelper {
@WorkerThread
@NonNull
public synchronized List<HistoryItem> getLastHundredItems() {
synchronized List<HistoryItem> getLastHundredItems() {
mDatabase = openIfNecessary();
List<HistoryItem> itemList = new ArrayList<>(100);
Cursor cursor = mDatabase.query(TABLE_HISTORY, null, null, null, null, null, KEY_TIME_VISITED + " DESC", "100");
while (cursor.moveToNext()) {
HistoryItem item = new HistoryItem();
item.setUrl(cursor.getString(1));
item.setTitle(cursor.getString(2));
item.setImageId(R.drawable.ic_history);
itemList.add(item);
itemList.add(fromCursor(cursor));
}
cursor.close();
@ -195,18 +201,14 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -195,18 +201,14 @@ public class HistoryDatabase extends SQLiteOpenHelper {
@WorkerThread
@NonNull
public synchronized List<HistoryItem> getAllHistoryItems() {
synchronized List<HistoryItem> getAllHistoryItems() {
mDatabase = openIfNecessary();
List<HistoryItem> itemList = new ArrayList<>();
Cursor cursor = mDatabase.query(TABLE_HISTORY, null, null, null, null, null, KEY_TIME_VISITED + " DESC");
while (cursor.moveToNext()) {
HistoryItem item = new HistoryItem();
item.setUrl(cursor.getString(1));
item.setTitle(cursor.getString(2));
item.setImageId(R.drawable.ic_history);
itemList.add(item);
itemList.add(fromCursor(cursor));
}
cursor.close();
@ -215,7 +217,7 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -215,7 +217,7 @@ public class HistoryDatabase extends SQLiteOpenHelper {
}
@WorkerThread
public synchronized long getHistoryItemsCount() {
synchronized long getHistoryItemsCount() {
return DatabaseUtils.queryNumEntries(mDatabase, TABLE_HISTORY);
}
}

84
app/src/main/java/acr/browser/lightning/database/HistoryModel.java

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
package acr.browser.lightning.database;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.anthonycr.bonsai.Completable;
import com.anthonycr.bonsai.CompletableAction;
import com.anthonycr.bonsai.CompletableSubscriber;
import com.anthonycr.bonsai.Single;
import com.anthonycr.bonsai.SingleAction;
import com.anthonycr.bonsai.SingleSubscriber;
import java.util.List;
/**
* A model class providing reactive bindings
* with the underlying history database.
*/
public final class HistoryModel {
private HistoryModel() {}
@NonNull
public static Completable deleteHistory() {
return Completable.create(new CompletableAction() {
@Override
public void onSubscribe(@NonNull CompletableSubscriber subscriber) {
HistoryDatabase.getInstance().deleteHistory();
subscriber.onComplete();
}
});
}
@NonNull
public static Completable deleteHistoryItem(@NonNull final String url) {
return Completable.create(new CompletableAction() {
@Override
public void onSubscribe(@NonNull CompletableSubscriber subscriber) {
HistoryDatabase.getInstance().deleteHistoryItem(url);
subscriber.onComplete();
}
});
}
@NonNull
public static Completable visitHistoryItem(@NonNull final String url, @Nullable final String title) {
return Completable.create(new CompletableAction() {
@Override
public void onSubscribe(@NonNull CompletableSubscriber subscriber) {
HistoryDatabase.getInstance().visitHistoryItem(url, title);
subscriber.onComplete();
}
});
}
@NonNull
public static Single<List<HistoryItem>> findHistoryItemsContaining(@NonNull final String query) {
return Single.create(new SingleAction<List<HistoryItem>>() {
@Override
public void onSubscribe(@NonNull SingleSubscriber<List<HistoryItem>> subscriber) {
List<HistoryItem> result = HistoryDatabase.getInstance().findItemsContaining(query);
subscriber.onItem(result);
subscriber.onComplete();
}
});
}
@NonNull
public static Single<List<HistoryItem>> lastHundredVisitedHistoryItems() {
return Single.create(new SingleAction<List<HistoryItem>>() {
@Override
public void onSubscribe(@NonNull SingleSubscriber<List<HistoryItem>> subscriber) {
List<HistoryItem> result = HistoryDatabase.getInstance().getLastHundredItems();
subscriber.onItem(result);
subscriber.onComplete();
}
});
}
}

350
app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java

@ -12,6 +12,7 @@ import android.widget.ArrayAdapter; @@ -12,6 +12,7 @@ import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import com.anthonycr.bonsai.CompletableOnSubscribe;
import com.anthonycr.bonsai.Schedulers;
import com.squareup.otto.Bus;
@ -27,8 +28,8 @@ import acr.browser.lightning.bus.BrowserEvents; @@ -27,8 +28,8 @@ import acr.browser.lightning.bus.BrowserEvents;
import acr.browser.lightning.constant.BookmarkPage;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.database.BookmarkManager;
import acr.browser.lightning.database.HistoryDatabase;
import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.database.HistoryModel;
import acr.browser.lightning.preference.PreferenceManager;
import acr.browser.lightning.utils.Utils;
@ -41,7 +42,6 @@ public class LightningDialogBuilder { @@ -41,7 +42,6 @@ public class LightningDialogBuilder {
@Inject BookmarkManager mBookmarkManager;
@Inject PreferenceManager mPreferenceManager;
@Inject HistoryDatabase mHistoryDatabase;
@Inject Bus mEventBus;
@Inject
@ -82,44 +82,44 @@ public class LightningDialogBuilder { @@ -82,44 +82,44 @@ public class LightningDialogBuilder {
public void showLongPressedDialogForBookmarkUrl(@NonNull final Activity activity, @NonNull final HistoryItem item) {
BrowserDialog.show(activity, R.string.action_bookmarks,
new BrowserDialog.Item(R.string.dialog_open_new_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(item.getUrl(), BrowserEvents.OpenUrlInNewTab.Location.NEW_TAB));
}
},
new BrowserDialog.Item(R.string.dialog_open_background_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(item.getUrl(), BrowserEvents.OpenUrlInNewTab.Location.BACKGROUND));
}
},
new BrowserDialog.Item(R.string.dialog_open_incognito_tab, activity instanceof MainActivity) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(item.getUrl(), BrowserEvents.OpenUrlInNewTab.Location.INCOGNITO));
}
},
new BrowserDialog.Item(R.string.dialog_copy_link) {
@Override
public void onClick() {
BrowserApp.copyToClipboard(activity, item.getUrl());
}
},
new BrowserDialog.Item(R.string.dialog_remove_bookmark) {
@Override
public void onClick() {
if (mBookmarkManager.deleteBookmark(item)) {
mEventBus.post(new BookmarkEvents.Deleted(item));
new BrowserDialog.Item(R.string.dialog_open_new_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(item.getUrl(), BrowserEvents.OpenUrlInNewTab.Location.NEW_TAB));
}
},
new BrowserDialog.Item(R.string.dialog_open_background_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(item.getUrl(), BrowserEvents.OpenUrlInNewTab.Location.BACKGROUND));
}
},
new BrowserDialog.Item(R.string.dialog_open_incognito_tab, activity instanceof MainActivity) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(item.getUrl(), BrowserEvents.OpenUrlInNewTab.Location.INCOGNITO));
}
},
new BrowserDialog.Item(R.string.dialog_copy_link) {
@Override
public void onClick() {
BrowserApp.copyToClipboard(activity, item.getUrl());
}
}
},
new BrowserDialog.Item(R.string.dialog_edit_bookmark) {
@Override
public void onClick() {
showEditBookmarkDialog(activity, item);
}
});
},
new BrowserDialog.Item(R.string.dialog_remove_bookmark) {
@Override
public void onClick() {
if (mBookmarkManager.deleteBookmark(item)) {
mEventBus.post(new BookmarkEvents.Deleted(item));
}
}
},
new BrowserDialog.Item(R.string.dialog_edit_bookmark) {
@Override
public void onClick() {
showEditBookmarkDialog(activity, item);
}
});
}
private void showEditBookmarkDialog(@NonNull final Activity activity, @NonNull final HistoryItem item) {
@ -131,29 +131,29 @@ public class LightningDialogBuilder { @@ -131,29 +131,29 @@ public class LightningDialogBuilder {
final EditText getUrl = (EditText) dialogLayout.findViewById(R.id.bookmark_url);
getUrl.setText(item.getUrl());
final AutoCompleteTextView getFolder =
(AutoCompleteTextView) dialogLayout.findViewById(R.id.bookmark_folder);
(AutoCompleteTextView) dialogLayout.findViewById(R.id.bookmark_folder);
getFolder.setHint(R.string.folder);
getFolder.setText(item.getFolder());
final List<String> folders = mBookmarkManager.getFolderTitles();
final ArrayAdapter<String> suggestionsAdapter = new ArrayAdapter<>(activity,
android.R.layout.simple_dropdown_item_1line, folders);
android.R.layout.simple_dropdown_item_1line, folders);
getFolder.setThreshold(1);
getFolder.setAdapter(suggestionsAdapter);
editBookmarkDialog.setView(dialogLayout);
editBookmarkDialog.setPositiveButton(activity.getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
HistoryItem editedItem = new HistoryItem();
editedItem.setTitle(getTitle.getText().toString());
editedItem.setUrl(getUrl.getText().toString());
editedItem.setUrl(getUrl.getText().toString());
editedItem.setFolder(getFolder.getText().toString());
mBookmarkManager.editBookmark(item, editedItem);
mEventBus.post(new BookmarkEvents.BookmarkChanged(item, editedItem));
}
});
@Override
public void onClick(DialogInterface dialog, int which) {
HistoryItem editedItem = new HistoryItem();
editedItem.setTitle(getTitle.getText().toString());
editedItem.setUrl(getUrl.getText().toString());
editedItem.setUrl(getUrl.getText().toString());
editedItem.setFolder(getFolder.getText().toString());
mBookmarkManager.editBookmark(item, editedItem);
mEventBus.post(new BookmarkEvents.BookmarkChanged(item, editedItem));
}
});
Dialog dialog = editBookmarkDialog.show();
BrowserDialog.setDialogSize(activity, dialog);
}
@ -161,149 +161,145 @@ public class LightningDialogBuilder { @@ -161,149 +161,145 @@ public class LightningDialogBuilder {
public void showBookmarkFolderLongPressedDialog(@NonNull final Activity activity, @NonNull final HistoryItem item) {
BrowserDialog.show(activity, R.string.action_folder,
new BrowserDialog.Item(R.string.dialog_rename_folder) {
@Override
public void onClick() {
showRenameFolderDialog(activity, item);
}
},
new BrowserDialog.Item(R.string.dialog_remove_folder) {
@Override
public void onClick() {
mBookmarkManager.deleteFolder(item.getTitle());
mEventBus.post(new BookmarkEvents.Deleted(item));
}
});
new BrowserDialog.Item(R.string.dialog_rename_folder) {
@Override
public void onClick() {
showRenameFolderDialog(activity, item);
}
},
new BrowserDialog.Item(R.string.dialog_remove_folder) {
@Override
public void onClick() {
mBookmarkManager.deleteFolder(item.getTitle());
mEventBus.post(new BookmarkEvents.Deleted(item));
}
});
}
private void showRenameFolderDialog(@NonNull final Activity activity, @NonNull final HistoryItem item) {
BrowserDialog.showEditText(activity, R.string.title_rename_folder,
R.string.hint_title, item.getTitle(),
R.string.action_ok, new BrowserDialog.EditorListener() {
@Override
public void onClick(String text) {
if (!TextUtils.isEmpty(text)) {
final String oldTitle = item.getTitle();
final HistoryItem editedItem = new HistoryItem();
editedItem.setTitle(text);
editedItem.setUrl(Constants.FOLDER + text);
editedItem.setFolder(item.getFolder());
editedItem.setIsFolder(true);
mBookmarkManager.renameFolder(oldTitle, text);
mEventBus.post(new BookmarkEvents.BookmarkChanged(item, editedItem));
R.string.hint_title, item.getTitle(),
R.string.action_ok, new BrowserDialog.EditorListener() {
@Override
public void onClick(String text) {
if (!TextUtils.isEmpty(text)) {
final String oldTitle = item.getTitle();
final HistoryItem editedItem = new HistoryItem();
editedItem.setTitle(text);
editedItem.setUrl(Constants.FOLDER + text);
editedItem.setFolder(item.getFolder());
editedItem.setIsFolder(true);
mBookmarkManager.renameFolder(oldTitle, text);
mEventBus.post(new BookmarkEvents.BookmarkChanged(item, editedItem));
}
}
}
});
});
}
public void showLongPressedHistoryLinkDialog(@NonNull final Activity activity, @NonNull final String url) {
BrowserDialog.show(activity, R.string.action_history,
new BrowserDialog.Item(R.string.dialog_open_new_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url));
}
},
new BrowserDialog.Item(R.string.dialog_open_background_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url, BrowserEvents.OpenUrlInNewTab.Location.BACKGROUND));
}
},
new BrowserDialog.Item(R.string.dialog_open_incognito_tab, activity instanceof MainActivity) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url, BrowserEvents.OpenUrlInNewTab.Location.INCOGNITO));
}
},
new BrowserDialog.Item(R.string.dialog_copy_link) {
@Override
public void onClick() {
BrowserApp.copyToClipboard(activity, url);
}
},
new BrowserDialog.Item(R.string.dialog_remove_from_history) {
@Override
public void onClick() {
BrowserApp.getIOThread().execute(new Runnable() {
@Override
public void run() {
mHistoryDatabase.deleteHistoryItem(url);
// openHistory();
Schedulers.main().execute(new Runnable() {
@Override
public void run() {
mEventBus.post(new BrowserEvents.OpenHistoryInCurrentTab());
}
});
}
});
}
});
new BrowserDialog.Item(R.string.dialog_open_new_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url));
}
},
new BrowserDialog.Item(R.string.dialog_open_background_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url, BrowserEvents.OpenUrlInNewTab.Location.BACKGROUND));
}
},
new BrowserDialog.Item(R.string.dialog_open_incognito_tab, activity instanceof MainActivity) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url, BrowserEvents.OpenUrlInNewTab.Location.INCOGNITO));
}
},
new BrowserDialog.Item(R.string.dialog_copy_link) {
@Override
public void onClick() {
BrowserApp.copyToClipboard(activity, url);
}
},
new BrowserDialog.Item(R.string.dialog_remove_from_history) {
@Override
public void onClick() {
HistoryModel.deleteHistoryItem(url)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.main())
.subscribe(new CompletableOnSubscribe() {
@Override
public void onComplete() {
mEventBus.post(new BrowserEvents.OpenHistoryInCurrentTab());
}
});
}
});
}
// 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) {
BrowserDialog.show(activity, url.replace(Constants.HTTP, ""),
new BrowserDialog.Item(R.string.dialog_open_new_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url));
}
},
new BrowserDialog.Item(R.string.dialog_open_background_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url, BrowserEvents.OpenUrlInNewTab.Location.BACKGROUND));
}
},
new BrowserDialog.Item(R.string.dialog_open_incognito_tab, activity instanceof MainActivity) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url, BrowserEvents.OpenUrlInNewTab.Location.INCOGNITO));
}
},
new BrowserDialog.Item(R.string.dialog_copy_link) {
@Override
public void onClick() {
BrowserApp.copyToClipboard(activity, url);
}
},
new BrowserDialog.Item(R.string.dialog_download_image) {
@Override
public void onClick() {
Utils.downloadFile(activity, mPreferenceManager, url, userAgent, "attachment");
}
});
new BrowserDialog.Item(R.string.dialog_open_new_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url));
}
},
new BrowserDialog.Item(R.string.dialog_open_background_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url, BrowserEvents.OpenUrlInNewTab.Location.BACKGROUND));
}
},
new BrowserDialog.Item(R.string.dialog_open_incognito_tab, activity instanceof MainActivity) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url, BrowserEvents.OpenUrlInNewTab.Location.INCOGNITO));
}
},
new BrowserDialog.Item(R.string.dialog_copy_link) {
@Override
public void onClick() {
BrowserApp.copyToClipboard(activity, url);
}
},
new BrowserDialog.Item(R.string.dialog_download_image) {
@Override
public void onClick() {
Utils.downloadFile(activity, mPreferenceManager, url, userAgent, "attachment");
}
});
}
public void showLongPressLinkDialog(@NonNull final Activity activity, final String url) {
BrowserDialog.show(activity, url,
new BrowserDialog.Item(R.string.dialog_open_new_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url));
}
},
new BrowserDialog.Item(R.string.dialog_open_background_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url, BrowserEvents.OpenUrlInNewTab.Location.BACKGROUND));
}
},
new BrowserDialog.Item(R.string.dialog_open_incognito_tab, activity instanceof MainActivity) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url, BrowserEvents.OpenUrlInNewTab.Location.INCOGNITO));
}
},
new BrowserDialog.Item(R.string.dialog_copy_link) {
@Override
public void onClick() {
BrowserApp.copyToClipboard(activity, url);
}
});
new BrowserDialog.Item(R.string.dialog_open_new_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url));
}
},
new BrowserDialog.Item(R.string.dialog_open_background_tab) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url, BrowserEvents.OpenUrlInNewTab.Location.BACKGROUND));
}
},
new BrowserDialog.Item(R.string.dialog_open_incognito_tab, activity instanceof MainActivity) {
@Override
public void onClick() {
mEventBus.post(new BrowserEvents.OpenUrlInNewTab(url, BrowserEvents.OpenUrlInNewTab.Location.INCOGNITO));
}
},
new BrowserDialog.Item(R.string.dialog_copy_link) {
@Override
public void onClick() {
BrowserApp.copyToClipboard(activity, url);
}
});
}
}

7
app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java

@ -16,11 +16,8 @@ import android.support.annotation.NonNull; @@ -16,11 +16,8 @@ import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.webkit.WebView;
import javax.inject.Inject;
import acr.browser.lightning.R;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.database.HistoryDatabase;
import acr.browser.lightning.dialog.BrowserDialog;
import acr.browser.lightning.utils.Utils;
import acr.browser.lightning.utils.WebUtils;
@ -45,8 +42,6 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme @@ -45,8 +42,6 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme
private Activity mActivity;
private Handler mMessageHandler;
@Inject HistoryDatabase mHistoryDatabase;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -200,7 +195,7 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme @@ -200,7 +195,7 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme
}
private void clearHistory() {
WebUtils.clearHistory(getActivity(), mHistoryDatabase);
WebUtils.clearHistory(getActivity());
mMessageHandler.sendEmptyMessage(1);
}

63
app/src/main/java/acr/browser/lightning/search/SuggestionsAdapter.java

@ -40,8 +40,8 @@ import javax.inject.Inject; @@ -40,8 +40,8 @@ import javax.inject.Inject;
import acr.browser.lightning.R;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.database.BookmarkManager;
import acr.browser.lightning.database.HistoryDatabase;
import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.database.HistoryModel;
import acr.browser.lightning.preference.PreferenceManager;
import acr.browser.lightning.utils.ThemeUtils;
@ -65,7 +65,6 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable { @@ -65,7 +65,6 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
private final Comparator<HistoryItem> mFilterComparator = new SuggestionsComparator();
@Inject HistoryDatabase mDatabaseHandler;
@Inject BookmarkManager mBookmarkManager;
@Inject PreferenceManager mPreferenceManager;
@ -257,7 +256,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable { @@ -257,7 +256,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
subscriber.onComplete();
}
}).subscribeOn(FILTER_SCHEDULER)
.observeOn(Schedulers.main())
.observeOn(Schedulers.main())
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
@Override
public void onItem(@Nullable List<HistoryItem> item) {
@ -278,7 +277,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable { @@ -278,7 +277,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
break;
}
if (mAllBookmarks.get(n).getTitle().toLowerCase(Locale.getDefault())
.startsWith(query)) {
.startsWith(query)) {
bookmarks.add(mAllBookmarks.get(n));
counter++;
} else if (mAllBookmarks.get(n).getUrl().contains(query)) {
@ -303,18 +302,6 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable { @@ -303,18 +302,6 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
}
}
@NonNull
private Single<List<HistoryItem>> getHistoryForQuery(@NonNull final String query) {
return Single.create(new SingleAction<List<HistoryItem>>() {
@Override
public void onSubscribe(@NonNull SingleSubscriber<List<HistoryItem>> subscriber) {
List<HistoryItem> historyList = mDatabaseHandler.findItemsContaining(query);
subscriber.onItem(historyList);
subscriber.onComplete();
}
});
}
private boolean shouldRequestNetwork() {
return !mIsIncognito && mSuggestionChoice != PreferenceManager.Suggestion.SUGGESTION_NONE;
}
@ -338,35 +325,35 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable { @@ -338,35 +325,35 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
if (mSuggestionsAdapter.shouldRequestNetwork() && !SuggestionsManager.isRequestInProgress()) {
mSuggestionsAdapter.getSuggestionsForQuery(query)
.subscribeOn(Schedulers.worker())
.subscribeOn(Schedulers.worker())
.observeOn(Schedulers.main())
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
@Override
public void onItem(@Nullable List<HistoryItem> item) {
mSuggestionsAdapter.combineResults(null, null, item);
}
});
}
mSuggestionsAdapter.getBookmarksForQuery(query)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.main())
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
@Override
public void onItem(@Nullable List<HistoryItem> item) {
mSuggestionsAdapter.combineResults(null, null, item);
mSuggestionsAdapter.combineResults(item, null, null);
}
});
}
mSuggestionsAdapter.getBookmarksForQuery(query)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.main())
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
@Override
public void onItem(@Nullable List<HistoryItem> item) {
mSuggestionsAdapter.combineResults(item, null, null);
}
});
mSuggestionsAdapter.getHistoryForQuery(query)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.main())
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
@Override
public void onItem(@Nullable List<HistoryItem> item) {
mSuggestionsAdapter.combineResults(null, item, null);
}
});
HistoryModel.findHistoryItemsContaining(query)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.main())
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
@Override
public void onItem(@Nullable List<HistoryItem> item) {
mSuggestionsAdapter.combineResults(null, item, null);
}
});
results.count = 1;
return results;
}

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

@ -11,7 +11,9 @@ import android.webkit.WebStorage; @@ -11,7 +11,9 @@ import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewDatabase;
import acr.browser.lightning.database.HistoryDatabase;
import com.anthonycr.bonsai.Schedulers;
import acr.browser.lightning.database.HistoryModel;
/**
* Copyright 8/4/2015 Anthony Restaino
@ -34,8 +36,10 @@ public class WebUtils { @@ -34,8 +36,10 @@ public class WebUtils {
WebStorage.getInstance().deleteAllData();
}
public static void clearHistory(@NonNull Context context, @NonNull HistoryDatabase historyDatabase) {
historyDatabase.deleteHistory();
public static void clearHistory(@NonNull Context context) {
HistoryModel.deleteHistory()
.subscribeOn(Schedulers.io())
.subscribe();
WebViewDatabase m = WebViewDatabase.getInstance(context);
m.clearFormData();
m.clearHttpAuthUsernamePassword();

4
build.gradle

@ -17,10 +17,6 @@ allprojects { @@ -17,10 +17,6 @@ allprojects {
}
ext {
// Necessary for Bonsai submodule
versionCode = 1
versionName = '1.0'
minSdkVersion = 14
targetSdkVersion = 25
buildToolsVersion = '25.0.2'

Loading…
Cancel
Save