From a02ac29057b32c7aeddbaa3e15270057d80c00fe Mon Sep 17 00:00:00 2001 From: anthony restaino Date: Fri, 9 Jun 2017 20:37:41 -0400 Subject: [PATCH] Switching HistoryDatabase to implement reactive interface --- .../lightning/activity/BrowserActivity.java | 6 +- .../acr/browser/lightning/app/AppModule.java | 13 +- .../lightning/constant/HistoryPage.java | 3 +- .../database/history/HistoryDatabase.java | 163 +++++++++++------- .../database/history/HistoryModel.java | 80 ++------- .../dialog/LightningDialogBuilder.java | 3 +- .../fragment/PrivacySettingsFragment.java | 8 +- .../lightning/search/SuggestionsAdapter.java | 10 +- .../acr/browser/lightning/utils/WebUtils.java | 4 +- 9 files changed, 148 insertions(+), 142 deletions(-) diff --git a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java index e5bf612..ff28dff 100644 --- a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java +++ b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java @@ -185,6 +185,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements // The singleton BookmarkManager @Inject BookmarkModel mBookmarkManager; + @Inject HistoryModel mHistoryModel; + @Inject LightningDialogBuilder mBookmarksDialogBuilder; private TabsManager mTabsManager; @@ -1250,7 +1252,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements Log.d(TAG, "Cache Cleared"); } if (mPreferences.getClearHistoryExitEnabled() && !isIncognito()) { - WebUtils.clearHistory(this); + WebUtils.clearHistory(this, mHistoryModel); Log.d(TAG, "History Cleared"); } if (mPreferences.getClearCookiesExitEnabled() && !isIncognito()) { @@ -1584,7 +1586,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements return; } - HistoryModel.visitHistoryItem(url, title) + mHistoryModel.visitHistoryItem(url, title) .subscribeOn(Schedulers.io()) .subscribe(new CompletableOnSubscribe() { @Override diff --git a/app/src/main/java/acr/browser/lightning/app/AppModule.java b/app/src/main/java/acr/browser/lightning/app/AppModule.java index 400d783..9ae607a 100644 --- a/app/src/main/java/acr/browser/lightning/app/AppModule.java +++ b/app/src/main/java/acr/browser/lightning/app/AppModule.java @@ -12,6 +12,8 @@ import acr.browser.lightning.database.bookmark.BookmarkDatabase; import acr.browser.lightning.database.bookmark.BookmarkModel; import acr.browser.lightning.database.downloads.DownloadsDatabase; import acr.browser.lightning.database.downloads.DownloadsModel; +import acr.browser.lightning.database.history.HistoryDatabase; +import acr.browser.lightning.database.history.HistoryModel; import dagger.Module; import dagger.Provides; @@ -36,17 +38,24 @@ public class AppModule { @NonNull @Provides @Singleton - public BookmarkModel provideBookmarkMode() { + public BookmarkModel provideBookmarkModel() { return new BookmarkDatabase(mApp); } @NonNull @Provides @Singleton - public DownloadsModel provideDownloadsMode() { + public DownloadsModel provideDownloadsModel() { return new DownloadsDatabase(mApp); } + @NonNull + @Provides + @Singleton + public HistoryModel providesHistoryModel() { + return new HistoryDatabase(mApp); + } + @NonNull @Provides @Singleton diff --git a/app/src/main/java/acr/browser/lightning/constant/HistoryPage.java b/app/src/main/java/acr/browser/lightning/constant/HistoryPage.java index 11143fc..0e102ca 100644 --- a/app/src/main/java/acr/browser/lightning/constant/HistoryPage.java +++ b/app/src/main/java/acr/browser/lightning/constant/HistoryPage.java @@ -64,6 +64,7 @@ public class HistoryPage { @NonNull private final String mTitle; @Inject Application mApp; + @Inject HistoryModel mHistoryModel; public HistoryPage() { BrowserApp.getAppComponent().inject(this); @@ -77,7 +78,7 @@ public class HistoryPage { public void onSubscribe(@NonNull final SingleSubscriber subscriber) { final StringBuilder historyBuilder = new StringBuilder(HEADING_1 + mTitle + HEADING_2); - HistoryModel.lastHundredVisitedHistoryItems() + mHistoryModel.lastHundredVisitedHistoryItems() .subscribe(new SingleOnSubscribe>() { @Override public void onItem(@Nullable List item) { diff --git a/app/src/main/java/acr/browser/lightning/database/history/HistoryDatabase.java b/app/src/main/java/acr/browser/lightning/database/history/HistoryDatabase.java index e4e04ec..b61fa16 100644 --- a/app/src/main/java/acr/browser/lightning/database/history/HistoryDatabase.java +++ b/app/src/main/java/acr/browser/lightning/database/history/HistoryDatabase.java @@ -13,6 +13,13 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.WorkerThread; +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.ArrayList; import java.util.List; @@ -22,9 +29,15 @@ import javax.inject.Singleton; import acr.browser.lightning.R; import acr.browser.lightning.database.HistoryItem; + +/** + * The disk backed download database. + * See {@link HistoryModel} for method + * documentation. + */ @Singleton @WorkerThread -public class HistoryDatabase extends SQLiteOpenHelper { +public class HistoryDatabase extends SQLiteOpenHelper implements HistoryModel { // All Static variables // Database Version @@ -45,9 +58,8 @@ public class HistoryDatabase extends SQLiteOpenHelper { @Nullable private SQLiteDatabase mDatabase; @Inject - HistoryDatabase(@NonNull Application application) { + public HistoryDatabase(@NonNull Application application) { super(application, DATABASE_NAME, null, DATABASE_VERSION); - mDatabase = HistoryDatabase.this.getWritableDatabase(); } // Creating Tables @@ -87,33 +99,101 @@ public class HistoryDatabase extends SQLiteOpenHelper { return mDatabase; } - @WorkerThread - synchronized void deleteHistory() { - lazyDatabase().delete(TABLE_HISTORY, null, null); - lazyDatabase().close(); + @NonNull + @Override + public Completable deleteHistory() { + return Completable.create(new CompletableAction() { + @Override + public void onSubscribe(@NonNull CompletableSubscriber subscriber) { + lazyDatabase().delete(TABLE_HISTORY, null, null); + lazyDatabase().close(); + + subscriber.onComplete(); + } + }); } - @WorkerThread - synchronized void deleteHistoryItem(@NonNull String url) { - lazyDatabase().delete(TABLE_HISTORY, KEY_URL + " = ?", new String[]{url}); + @NonNull + @Override + public Completable deleteHistoryItem(@NonNull final String url) { + return Completable.create(new CompletableAction() { + @Override + public void onSubscribe(@NonNull CompletableSubscriber subscriber) { + lazyDatabase().delete(TABLE_HISTORY, KEY_URL + " = ?", new String[]{url}); + + subscriber.onComplete(); + } + }); } - @WorkerThread - synchronized void visitHistoryItem(@NonNull String url, @Nullable String title) { - ContentValues values = new ContentValues(); - values.put(KEY_TITLE, title == null ? "" : title); - values.put(KEY_TIME_VISITED, System.currentTimeMillis()); + @NonNull + @Override + public Completable visitHistoryItem(@NonNull final String url, @Nullable final String title) { + return Completable.create(new CompletableAction() { + @Override + public void onSubscribe(@NonNull CompletableSubscriber subscriber) { + ContentValues values = new ContentValues(); + values.put(KEY_TITLE, title == null ? "" : title); + values.put(KEY_TIME_VISITED, System.currentTimeMillis()); + + Cursor cursor = lazyDatabase().query(false, TABLE_HISTORY, new String[]{KEY_URL}, + KEY_URL + " = ?", new String[]{url}, null, null, null, "1"); + + if (cursor.getCount() > 0) { + lazyDatabase().update(TABLE_HISTORY, values, KEY_URL + " = ?", new String[]{url}); + } else { + addHistoryItem(new HistoryItem(url, title == null ? "" : title)); + } + + cursor.close(); + } + }); + } - Cursor cursor = lazyDatabase().query(false, TABLE_HISTORY, new String[]{KEY_URL}, - KEY_URL + " = ?", new String[]{url}, null, null, null, "1"); + @NonNull + @Override + public Single> findHistoryItemsContaining(@NonNull final String query) { + return Single.create(new SingleAction>() { + @Override + public void onSubscribe(@NonNull SingleSubscriber> subscriber) { + List itemList = new ArrayList<>(5); - if (cursor.getCount() > 0) { - lazyDatabase().update(TABLE_HISTORY, values, KEY_URL + " = ?", new String[]{url}); - } else { - addHistoryItem(new HistoryItem(url, title == null ? "" : title)); - } + String search = '%' + query + '%'; - cursor.close(); + Cursor cursor = lazyDatabase().query(TABLE_HISTORY, null, KEY_TITLE + " LIKE ? OR " + KEY_URL + " LIKE ?", + new String[]{search, search}, null, null, KEY_TIME_VISITED + " DESC", "5"); + + while (cursor.moveToNext()) { + itemList.add(fromCursor(cursor)); + } + + cursor.close(); + + subscriber.onItem(itemList); + subscriber.onComplete(); + } + }); + } + + @NonNull + @Override + public Single> lastHundredVisitedHistoryItems() { + return Single.create(new SingleAction>() { + @Override + public void onSubscribe(@NonNull SingleSubscriber> subscriber) { + List itemList = new ArrayList<>(100); + Cursor cursor = lazyDatabase().query(TABLE_HISTORY, null, null, null, null, null, KEY_TIME_VISITED + " DESC", "100"); + + while (cursor.moveToNext()) { + itemList.add(fromCursor(cursor)); + } + + cursor.close(); + + subscriber.onItem(itemList); + subscriber.onComplete(); + } + }); } @WorkerThread @@ -140,43 +220,6 @@ public class HistoryDatabase extends SQLiteOpenHelper { return m; } - @WorkerThread - @NonNull - synchronized List findItemsContaining(@Nullable String search) { - List itemList = new ArrayList<>(5); - if (search == null) { - return itemList; - } - - search = '%' + search + '%'; - - Cursor cursor = lazyDatabase().query(TABLE_HISTORY, null, KEY_TITLE + " LIKE ? OR " + KEY_URL + " LIKE ?", - new String[]{search, search}, null, null, KEY_TIME_VISITED + " DESC", "5"); - - while (cursor.moveToNext()) { - itemList.add(fromCursor(cursor)); - } - - cursor.close(); - - return itemList; - } - - @WorkerThread - @NonNull - synchronized List getLastHundredItems() { - List itemList = new ArrayList<>(100); - Cursor cursor = lazyDatabase().query(TABLE_HISTORY, null, null, null, null, null, KEY_TIME_VISITED + " DESC", "100"); - - while (cursor.moveToNext()) { - itemList.add(fromCursor(cursor)); - } - - cursor.close(); - - return itemList; - } - @WorkerThread @NonNull synchronized List getAllHistoryItems() { diff --git a/app/src/main/java/acr/browser/lightning/database/history/HistoryModel.java b/app/src/main/java/acr/browser/lightning/database/history/HistoryModel.java index 185ebcf..2aeb631 100644 --- a/app/src/main/java/acr/browser/lightning/database/history/HistoryModel.java +++ b/app/src/main/java/acr/browser/lightning/database/history/HistoryModel.java @@ -4,24 +4,19 @@ 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; -import acr.browser.lightning.app.BrowserApp; import acr.browser.lightning.database.HistoryItem; /** - * A model class providing reactive bindings - * with the underlying history database. + * An interface that should be used to communicate + * with the history database. + *

+ * Created by anthonycr on 6/9/17. */ -public final class HistoryModel { - - private HistoryModel() {} +public interface HistoryModel { /** * An observable that deletes browser history. @@ -29,18 +24,7 @@ public final class HistoryModel { * @return a valid observable. */ @NonNull - public static Completable deleteHistory() { - return Completable.create(new CompletableAction() { - @Override - public void onSubscribe(@NonNull CompletableSubscriber subscriber) { - BrowserApp.getAppComponent() - .historyDatabase() - .deleteHistory(); - - subscriber.onComplete(); - } - }); - } + Completable deleteHistory(); /** * An observable that deletes the history @@ -50,18 +34,7 @@ public final class HistoryModel { * @return a valid observable. */ @NonNull - public static Completable deleteHistoryItem(@NonNull final String url) { - return Completable.create(new CompletableAction() { - @Override - public void onSubscribe(@NonNull CompletableSubscriber subscriber) { - BrowserApp.getAppComponent() - .historyDatabase() - .deleteHistoryItem(url); - - subscriber.onComplete(); - } - }); - } + Completable deleteHistoryItem(@NonNull final String url); /** * An observable that visits the URL by @@ -74,18 +47,7 @@ public final class HistoryModel { * @return a valid observable. */ @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) { - BrowserApp.getAppComponent() - .historyDatabase() - .visitHistoryItem(url, title); - - subscriber.onComplete(); - } - }); - } + Completable visitHistoryItem(@NonNull final String url, @Nullable final String title); /** * An observable that finds all history items @@ -100,18 +62,7 @@ public final class HistoryModel { * a list of history items. */ @NonNull - public static Single> findHistoryItemsContaining(@NonNull final String query) { - return Single.create(new SingleAction>() { - @Override - public void onSubscribe(@NonNull SingleSubscriber> subscriber) { - List result = BrowserApp.getAppComponent() - .historyDatabase().findItemsContaining(query); - - subscriber.onItem(result); - subscriber.onComplete(); - } - }); - } + Single> findHistoryItemsContaining(@NonNull final String query); /** * An observable that emits a list of the @@ -121,16 +72,5 @@ public final class HistoryModel { * a list of history items. */ @NonNull - public static Single> lastHundredVisitedHistoryItems() { - return Single.create(new SingleAction>() { - @Override - public void onSubscribe(@NonNull SingleSubscriber> subscriber) { - List result = BrowserApp.getAppComponent() - .historyDatabase().getLastHundredItems(); - - subscriber.onItem(result); - subscriber.onComplete(); - } - }); - } + Single> lastHundredVisitedHistoryItems(); } diff --git a/app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java b/app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java index 73fd6c2..26d9ed2 100644 --- a/app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java +++ b/app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java @@ -55,6 +55,7 @@ public class LightningDialogBuilder { @Inject BookmarkModel mBookmarkManager; @Inject DownloadsModel mDownloadsModel; + @Inject HistoryModel mHistoryModel; @Inject PreferenceManager mPreferenceManager; @Inject @@ -332,7 +333,7 @@ public class LightningDialogBuilder { new BrowserDialog.Item(R.string.dialog_remove_from_history) { @Override public void onClick() { - HistoryModel.deleteHistoryItem(url) + mHistoryModel.deleteHistoryItem(url) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.main()) .subscribe(new CompletableOnSubscribe() { diff --git a/app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java b/app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java index f3d6ecc..d386d07 100644 --- a/app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java +++ b/app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java @@ -20,8 +20,11 @@ import com.anthonycr.bonsai.CompletableOnSubscribe; import com.anthonycr.bonsai.CompletableSubscriber; import com.anthonycr.bonsai.Schedulers; +import javax.inject.Inject; + import acr.browser.lightning.R; import acr.browser.lightning.app.BrowserApp; +import acr.browser.lightning.database.history.HistoryModel; import acr.browser.lightning.dialog.BrowserDialog; import acr.browser.lightning.utils.Utils; import acr.browser.lightning.utils.WebUtils; @@ -45,6 +48,8 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme private Activity mActivity; + @Inject HistoryModel mHistoryModel; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -187,7 +192,8 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme public void onSubscribe(@NonNull CompletableSubscriber subscriber) { Activity activity = getActivity(); if (activity != null) { - WebUtils.clearHistory(activity); + // TODO: 6/9/17 clearHistory is not synchronous + WebUtils.clearHistory(activity, mHistoryModel); subscriber.onComplete(); } subscriber.onError(new RuntimeException("Activity was null in clearHistory")); diff --git a/app/src/main/java/acr/browser/lightning/search/SuggestionsAdapter.java b/app/src/main/java/acr/browser/lightning/search/SuggestionsAdapter.java index 2b3dd52..ccb4281 100644 --- a/app/src/main/java/acr/browser/lightning/search/SuggestionsAdapter.java +++ b/app/src/main/java/acr/browser/lightning/search/SuggestionsAdapter.java @@ -67,6 +67,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable { @Inject BookmarkModel mBookmarkManager; @Inject PreferenceManager mPreferenceManager; + @Inject HistoryModel mHistoryModel; @Inject Application mApplication; private final List mAllBookmarks = new ArrayList<>(5); @@ -197,7 +198,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable { @NonNull @Override public Filter getFilter() { - return new SearchFilter(this); + return new SearchFilter(this, mHistoryModel); } private synchronized void publishResults(@NonNull List list) { @@ -318,9 +319,12 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable { private static class SearchFilter extends Filter { @NonNull private final SuggestionsAdapter mSuggestionsAdapter; + @NonNull private final HistoryModel mHistoryModel; - SearchFilter(@NonNull SuggestionsAdapter suggestionsAdapter) { + SearchFilter(@NonNull SuggestionsAdapter suggestionsAdapter, + @NonNull HistoryModel historyModel) { mSuggestionsAdapter = suggestionsAdapter; + mHistoryModel = historyModel; } @NonNull @@ -355,7 +359,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable { } }); - HistoryModel.findHistoryItemsContaining(query) + mHistoryModel.findHistoryItemsContaining(query) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.main()) .subscribe(new SingleOnSubscribe>() { diff --git a/app/src/main/java/acr/browser/lightning/utils/WebUtils.java b/app/src/main/java/acr/browser/lightning/utils/WebUtils.java index 2ae62c6..7b7825c 100644 --- a/app/src/main/java/acr/browser/lightning/utils/WebUtils.java +++ b/app/src/main/java/acr/browser/lightning/utils/WebUtils.java @@ -36,8 +36,8 @@ public class WebUtils { WebStorage.getInstance().deleteAllData(); } - public static void clearHistory(@NonNull Context context) { - HistoryModel.deleteHistory() + public static void clearHistory(@NonNull Context context, @NonNull HistoryModel historyModel) { + historyModel.deleteHistory() .subscribeOn(Schedulers.io()) .subscribe(); WebViewDatabase m = WebViewDatabase.getInstance(context);