Browse Source

Switching HistoryDatabase to implement reactive interface

master
anthony restaino 7 years ago
parent
commit
a02ac29057
  1. 6
      app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java
  2. 13
      app/src/main/java/acr/browser/lightning/app/AppModule.java
  3. 3
      app/src/main/java/acr/browser/lightning/constant/HistoryPage.java
  4. 163
      app/src/main/java/acr/browser/lightning/database/history/HistoryDatabase.java
  5. 80
      app/src/main/java/acr/browser/lightning/database/history/HistoryModel.java
  6. 3
      app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java
  7. 8
      app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java
  8. 10
      app/src/main/java/acr/browser/lightning/search/SuggestionsAdapter.java
  9. 4
      app/src/main/java/acr/browser/lightning/utils/WebUtils.java

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

@ -185,6 +185,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
// The singleton BookmarkManager // The singleton BookmarkManager
@Inject BookmarkModel mBookmarkManager; @Inject BookmarkModel mBookmarkManager;
@Inject HistoryModel mHistoryModel;
@Inject LightningDialogBuilder mBookmarksDialogBuilder; @Inject LightningDialogBuilder mBookmarksDialogBuilder;
private TabsManager mTabsManager; private TabsManager mTabsManager;
@ -1250,7 +1252,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
Log.d(TAG, "Cache Cleared"); Log.d(TAG, "Cache Cleared");
} }
if (mPreferences.getClearHistoryExitEnabled() && !isIncognito()) { if (mPreferences.getClearHistoryExitEnabled() && !isIncognito()) {
WebUtils.clearHistory(this); WebUtils.clearHistory(this, mHistoryModel);
Log.d(TAG, "History Cleared"); Log.d(TAG, "History Cleared");
} }
if (mPreferences.getClearCookiesExitEnabled() && !isIncognito()) { if (mPreferences.getClearCookiesExitEnabled() && !isIncognito()) {
@ -1584,7 +1586,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
return; return;
} }
HistoryModel.visitHistoryItem(url, title) mHistoryModel.visitHistoryItem(url, title)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.subscribe(new CompletableOnSubscribe() { .subscribe(new CompletableOnSubscribe() {
@Override @Override

13
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.bookmark.BookmarkModel;
import acr.browser.lightning.database.downloads.DownloadsDatabase; import acr.browser.lightning.database.downloads.DownloadsDatabase;
import acr.browser.lightning.database.downloads.DownloadsModel; 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.Module;
import dagger.Provides; import dagger.Provides;
@ -36,17 +38,24 @@ public class AppModule {
@NonNull @NonNull
@Provides @Provides
@Singleton @Singleton
public BookmarkModel provideBookmarkMode() { public BookmarkModel provideBookmarkModel() {
return new BookmarkDatabase(mApp); return new BookmarkDatabase(mApp);
} }
@NonNull @NonNull
@Provides @Provides
@Singleton @Singleton
public DownloadsModel provideDownloadsMode() { public DownloadsModel provideDownloadsModel() {
return new DownloadsDatabase(mApp); return new DownloadsDatabase(mApp);
} }
@NonNull
@Provides
@Singleton
public HistoryModel providesHistoryModel() {
return new HistoryDatabase(mApp);
}
@NonNull @NonNull
@Provides @Provides
@Singleton @Singleton

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

@ -64,6 +64,7 @@ public class HistoryPage {
@NonNull private final String mTitle; @NonNull private final String mTitle;
@Inject Application mApp; @Inject Application mApp;
@Inject HistoryModel mHistoryModel;
public HistoryPage() { public HistoryPage() {
BrowserApp.getAppComponent().inject(this); BrowserApp.getAppComponent().inject(this);
@ -77,7 +78,7 @@ public class HistoryPage {
public void onSubscribe(@NonNull final SingleSubscriber<String> subscriber) { public void onSubscribe(@NonNull final SingleSubscriber<String> subscriber) {
final StringBuilder historyBuilder = new StringBuilder(HEADING_1 + mTitle + HEADING_2); final StringBuilder historyBuilder = new StringBuilder(HEADING_1 + mTitle + HEADING_2);
HistoryModel.lastHundredVisitedHistoryItems() mHistoryModel.lastHundredVisitedHistoryItems()
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() { .subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
@Override @Override
public void onItem(@Nullable List<HistoryItem> item) { public void onItem(@Nullable List<HistoryItem> item) {

163
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.Nullable;
import android.support.annotation.WorkerThread; 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.ArrayList;
import java.util.List; import java.util.List;
@ -22,9 +29,15 @@ import javax.inject.Singleton;
import acr.browser.lightning.R; import acr.browser.lightning.R;
import acr.browser.lightning.database.HistoryItem; import acr.browser.lightning.database.HistoryItem;
/**
* The disk backed download database.
* See {@link HistoryModel} for method
* documentation.
*/
@Singleton @Singleton
@WorkerThread @WorkerThread
public class HistoryDatabase extends SQLiteOpenHelper { public class HistoryDatabase extends SQLiteOpenHelper implements HistoryModel {
// All Static variables // All Static variables
// Database Version // Database Version
@ -45,9 +58,8 @@ public class HistoryDatabase extends SQLiteOpenHelper {
@Nullable private SQLiteDatabase mDatabase; @Nullable private SQLiteDatabase mDatabase;
@Inject @Inject
HistoryDatabase(@NonNull Application application) { public HistoryDatabase(@NonNull Application application) {
super(application, DATABASE_NAME, null, DATABASE_VERSION); super(application, DATABASE_NAME, null, DATABASE_VERSION);
mDatabase = HistoryDatabase.this.getWritableDatabase();
} }
// Creating Tables // Creating Tables
@ -87,33 +99,101 @@ public class HistoryDatabase extends SQLiteOpenHelper {
return mDatabase; return mDatabase;
} }
@WorkerThread @NonNull
synchronized void deleteHistory() { @Override
lazyDatabase().delete(TABLE_HISTORY, null, null); public Completable deleteHistory() {
lazyDatabase().close(); return Completable.create(new CompletableAction() {
@Override
public void onSubscribe(@NonNull CompletableSubscriber subscriber) {
lazyDatabase().delete(TABLE_HISTORY, null, null);
lazyDatabase().close();
subscriber.onComplete();
}
});
} }
@WorkerThread @NonNull
synchronized void deleteHistoryItem(@NonNull String url) { @Override
lazyDatabase().delete(TABLE_HISTORY, KEY_URL + " = ?", new String[]{url}); 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 @NonNull
synchronized void visitHistoryItem(@NonNull String url, @Nullable String title) { @Override
ContentValues values = new ContentValues(); public Completable visitHistoryItem(@NonNull final String url, @Nullable final String title) {
values.put(KEY_TITLE, title == null ? "" : title); return Completable.create(new CompletableAction() {
values.put(KEY_TIME_VISITED, System.currentTimeMillis()); @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}, @NonNull
KEY_URL + " = ?", new String[]{url}, null, null, null, "1"); @Override
public 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> itemList = new ArrayList<>(5);
if (cursor.getCount() > 0) { String search = '%' + query + '%';
lazyDatabase().update(TABLE_HISTORY, values, KEY_URL + " = ?", new String[]{url});
} else {
addHistoryItem(new HistoryItem(url, title == null ? "" : title));
}
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<List<HistoryItem>> lastHundredVisitedHistoryItems() {
return Single.create(new SingleAction<List<HistoryItem>>() {
@Override
public void onSubscribe(@NonNull SingleSubscriber<List<HistoryItem>> subscriber) {
List<HistoryItem> 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 @WorkerThread
@ -140,43 +220,6 @@ public class HistoryDatabase extends SQLiteOpenHelper {
return m; return m;
} }
@WorkerThread
@NonNull
synchronized List<HistoryItem> findItemsContaining(@Nullable String search) {
List<HistoryItem> 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<HistoryItem> getLastHundredItems() {
List<HistoryItem> 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 @WorkerThread
@NonNull @NonNull
synchronized List<HistoryItem> getAllHistoryItems() { synchronized List<HistoryItem> getAllHistoryItems() {

80
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 android.support.annotation.Nullable;
import com.anthonycr.bonsai.Completable; import com.anthonycr.bonsai.Completable;
import com.anthonycr.bonsai.CompletableAction;
import com.anthonycr.bonsai.CompletableSubscriber;
import com.anthonycr.bonsai.Single; import com.anthonycr.bonsai.Single;
import com.anthonycr.bonsai.SingleAction;
import com.anthonycr.bonsai.SingleSubscriber;
import java.util.List; import java.util.List;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.database.HistoryItem; import acr.browser.lightning.database.HistoryItem;
/** /**
* A model class providing reactive bindings * An interface that should be used to communicate
* with the underlying history database. * with the history database.
* <p>
* Created by anthonycr on 6/9/17.
*/ */
public final class HistoryModel { public interface HistoryModel {
private HistoryModel() {}
/** /**
* An observable that deletes browser history. * An observable that deletes browser history.
@ -29,18 +24,7 @@ public final class HistoryModel {
* @return a valid observable. * @return a valid observable.
*/ */
@NonNull @NonNull
public static Completable deleteHistory() { Completable deleteHistory();
return Completable.create(new CompletableAction() {
@Override
public void onSubscribe(@NonNull CompletableSubscriber subscriber) {
BrowserApp.getAppComponent()
.historyDatabase()
.deleteHistory();
subscriber.onComplete();
}
});
}
/** /**
* An observable that deletes the history * An observable that deletes the history
@ -50,18 +34,7 @@ public final class HistoryModel {
* @return a valid observable. * @return a valid observable.
*/ */
@NonNull @NonNull
public static Completable deleteHistoryItem(@NonNull final String url) { 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();
}
});
}
/** /**
* An observable that visits the URL by * An observable that visits the URL by
@ -74,18 +47,7 @@ public final class HistoryModel {
* @return a valid observable. * @return a valid observable.
*/ */
@NonNull @NonNull
public static Completable visitHistoryItem(@NonNull final String url, @Nullable final String title) { 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();
}
});
}
/** /**
* An observable that finds all history items * An observable that finds all history items
@ -100,18 +62,7 @@ public final class HistoryModel {
* a list of history items. * a list of history items.
*/ */
@NonNull @NonNull
public static Single<List<HistoryItem>> findHistoryItemsContaining(@NonNull final String query) { 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 = BrowserApp.getAppComponent()
.historyDatabase().findItemsContaining(query);
subscriber.onItem(result);
subscriber.onComplete();
}
});
}
/** /**
* An observable that emits a list of the * An observable that emits a list of the
@ -121,16 +72,5 @@ public final class HistoryModel {
* a list of history items. * a list of history items.
*/ */
@NonNull @NonNull
public static Single<List<HistoryItem>> lastHundredVisitedHistoryItems() { Single<List<HistoryItem>> lastHundredVisitedHistoryItems();
return Single.create(new SingleAction<List<HistoryItem>>() {
@Override
public void onSubscribe(@NonNull SingleSubscriber<List<HistoryItem>> subscriber) {
List<HistoryItem> result = BrowserApp.getAppComponent()
.historyDatabase().getLastHundredItems();
subscriber.onItem(result);
subscriber.onComplete();
}
});
}
} }

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

@ -55,6 +55,7 @@ public class LightningDialogBuilder {
@Inject BookmarkModel mBookmarkManager; @Inject BookmarkModel mBookmarkManager;
@Inject DownloadsModel mDownloadsModel; @Inject DownloadsModel mDownloadsModel;
@Inject HistoryModel mHistoryModel;
@Inject PreferenceManager mPreferenceManager; @Inject PreferenceManager mPreferenceManager;
@Inject @Inject
@ -332,7 +333,7 @@ public class LightningDialogBuilder {
new BrowserDialog.Item(R.string.dialog_remove_from_history) { new BrowserDialog.Item(R.string.dialog_remove_from_history) {
@Override @Override
public void onClick() { public void onClick() {
HistoryModel.deleteHistoryItem(url) mHistoryModel.deleteHistoryItem(url)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(Schedulers.main()) .observeOn(Schedulers.main())
.subscribe(new CompletableOnSubscribe() { .subscribe(new CompletableOnSubscribe() {

8
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.CompletableSubscriber;
import com.anthonycr.bonsai.Schedulers; import com.anthonycr.bonsai.Schedulers;
import javax.inject.Inject;
import acr.browser.lightning.R; import acr.browser.lightning.R;
import acr.browser.lightning.app.BrowserApp; import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.database.history.HistoryModel;
import acr.browser.lightning.dialog.BrowserDialog; import acr.browser.lightning.dialog.BrowserDialog;
import acr.browser.lightning.utils.Utils; import acr.browser.lightning.utils.Utils;
import acr.browser.lightning.utils.WebUtils; import acr.browser.lightning.utils.WebUtils;
@ -45,6 +48,8 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme
private Activity mActivity; private Activity mActivity;
@Inject HistoryModel mHistoryModel;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -187,7 +192,8 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme
public void onSubscribe(@NonNull CompletableSubscriber subscriber) { public void onSubscribe(@NonNull CompletableSubscriber subscriber) {
Activity activity = getActivity(); Activity activity = getActivity();
if (activity != null) { if (activity != null) {
WebUtils.clearHistory(activity); // TODO: 6/9/17 clearHistory is not synchronous
WebUtils.clearHistory(activity, mHistoryModel);
subscriber.onComplete(); subscriber.onComplete();
} }
subscriber.onError(new RuntimeException("Activity was null in clearHistory")); subscriber.onError(new RuntimeException("Activity was null in clearHistory"));

10
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 BookmarkModel mBookmarkManager;
@Inject PreferenceManager mPreferenceManager; @Inject PreferenceManager mPreferenceManager;
@Inject HistoryModel mHistoryModel;
@Inject Application mApplication; @Inject Application mApplication;
private final List<HistoryItem> mAllBookmarks = new ArrayList<>(5); private final List<HistoryItem> mAllBookmarks = new ArrayList<>(5);
@ -197,7 +198,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
@NonNull @NonNull
@Override @Override
public Filter getFilter() { public Filter getFilter() {
return new SearchFilter(this); return new SearchFilter(this, mHistoryModel);
} }
private synchronized void publishResults(@NonNull List<HistoryItem> list) { private synchronized void publishResults(@NonNull List<HistoryItem> list) {
@ -318,9 +319,12 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
private static class SearchFilter extends Filter { private static class SearchFilter extends Filter {
@NonNull private final SuggestionsAdapter mSuggestionsAdapter; @NonNull private final SuggestionsAdapter mSuggestionsAdapter;
@NonNull private final HistoryModel mHistoryModel;
SearchFilter(@NonNull SuggestionsAdapter suggestionsAdapter) { SearchFilter(@NonNull SuggestionsAdapter suggestionsAdapter,
@NonNull HistoryModel historyModel) {
mSuggestionsAdapter = suggestionsAdapter; mSuggestionsAdapter = suggestionsAdapter;
mHistoryModel = historyModel;
} }
@NonNull @NonNull
@ -355,7 +359,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
} }
}); });
HistoryModel.findHistoryItemsContaining(query) mHistoryModel.findHistoryItemsContaining(query)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(Schedulers.main()) .observeOn(Schedulers.main())
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() { .subscribe(new SingleOnSubscribe<List<HistoryItem>>() {

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

@ -36,8 +36,8 @@ public class WebUtils {
WebStorage.getInstance().deleteAllData(); WebStorage.getInstance().deleteAllData();
} }
public static void clearHistory(@NonNull Context context) { public static void clearHistory(@NonNull Context context, @NonNull HistoryModel historyModel) {
HistoryModel.deleteHistory() historyModel.deleteHistory()
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.subscribe(); .subscribe();
WebViewDatabase m = WebViewDatabase.getInstance(context); WebViewDatabase m = WebViewDatabase.getInstance(context);

Loading…
Cancel
Save