Commit 7705271f authored by Amit Kumar's avatar Amit Kumar

Bump version 1.0.2 and Merge branch 'browser-search-engine' with following features/fixes.

1. Use browser search engine settings for launcher suggestions.
parents 56159132 5febf31a
Pipeline #10017 passed with stage
in 5 minutes and 27 seconds
......@@ -4,7 +4,7 @@ apply plugin: 'io.fabric'
// Manifest version information!
def versionMajor = 1
def versionMinor = 0
def versionPatch = 1
def versionPatch = 2
android {
compileSdkVersion rootProject.ext.compileSdkVersion
......
package foundation.e.blisslauncher.features.suggestions;
package foundation.e.blisslauncher.core.network.duckduckgo;
public class AutoCompleteServiceRawResult {
public class DuckDuckGoResult {
private String phrase;
public AutoCompleteServiceRawResult(String phrase){
public DuckDuckGoResult(String phrase){
this.phrase = phrase;
}
......
package foundation.e.blisslauncher.features.suggestions;
package foundation.e.blisslauncher.core.network.duckduckgo;
import java.util.List;
......@@ -6,8 +6,7 @@ import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface AutoCompleteService {
public interface DuckDuckGoSuggestionService {
@GET("/ac/")
Observable<List<AutoCompleteServiceRawResult>> query(@Query("q") String query);
Observable<List<DuckDuckGoResult>> query(@Query("q") String query);
}
package foundation.e.blisslauncher.core.network.qwant;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class QwantData {
@SerializedName("items")
@Expose
private List<QwantItem> items = null;
public List<QwantItem> getItems() {
return items;
}
public void setItems(List<QwantItem> items) {
this.items = items;
}
}
package foundation.e.blisslauncher.core.network.qwant;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class QwantItem {
@SerializedName("value")
@Expose
private String value;
@SerializedName("suggestType")
@Expose
private Integer suggestType;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Integer getSuggestType() {
return suggestType;
}
public void setSuggestType(Integer suggestType) {
this.suggestType = suggestType;
}
}
package foundation.e.blisslauncher.core.network.qwant;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class QwantResult {
@SerializedName("status")
@Expose
private String status;
@SerializedName("data")
@Expose
private QwantData data;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public QwantData getData() {
return data;
}
public void setData(QwantData data) {
this.data = data;
}
}
package foundation.e.blisslauncher.core.network.qwant;
import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface QwantSuggestionService {
@GET("/api/suggest/")
Observable<QwantResult> query(@Query("q") String query);
}
......@@ -79,7 +79,6 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
......@@ -117,7 +116,6 @@ import foundation.e.blisslauncher.core.events.AppAddEvent;
import foundation.e.blisslauncher.core.events.AppChangeEvent;
import foundation.e.blisslauncher.core.events.AppRemoveEvent;
import foundation.e.blisslauncher.core.events.ShortcutAddEvent;
import foundation.e.blisslauncher.core.network.RetrofitService;
import foundation.e.blisslauncher.core.utils.AppUtils;
import foundation.e.blisslauncher.core.utils.Constants;
import foundation.e.blisslauncher.core.utils.GraphicsUtil;
......@@ -126,8 +124,9 @@ import foundation.e.blisslauncher.features.notification.NotificationRepository;
import foundation.e.blisslauncher.features.notification.NotificationService;
import foundation.e.blisslauncher.features.shortcuts.DeepShortcutManager;
import foundation.e.blisslauncher.features.suggestions.AutoCompleteAdapter;
import foundation.e.blisslauncher.features.suggestions.AutoCompleteService;
import foundation.e.blisslauncher.features.suggestions.AutoCompleteServiceResult;
import foundation.e.blisslauncher.features.suggestions.SearchSuggestionUtil;
import foundation.e.blisslauncher.features.suggestions.SuggestionProvider;
import foundation.e.blisslauncher.features.suggestions.SuggestionsResult;
import foundation.e.blisslauncher.features.usagestats.AppUsageStats;
import foundation.e.blisslauncher.features.weather.DeviceStatusService;
import foundation.e.blisslauncher.features.weather.ForecastBuilder;
......@@ -1243,7 +1242,7 @@ public class LauncherActivity extends AppCompatActivity implements
return searchForQuery(charSequence);
} else {
return Observable.just(
new AutoCompleteServiceResult(charSequence));
new SuggestionsResult(charSequence));
}
})
.subscribeOn(Schedulers.io())
......@@ -1406,19 +1405,19 @@ public class LauncherActivity extends AppCompatActivity implements
}
}
private ObservableSource<AutoCompleteServiceResult> searchForQuery(
private ObservableSource<SuggestionsResult> searchForQuery(
CharSequence charSequence) {
Observable<AutoCompleteServiceResult> launcherItems = searchForLauncherItems(
Observable<SuggestionsResult> launcherItems = searchForLauncherItems(
charSequence.toString()).subscribeOn(Schedulers.io());
Observable<AutoCompleteServiceResult> networkItems = searchForNetworkItems(
Observable<SuggestionsResult> networkItems = searchForNetworkItems(
charSequence).subscribeOn(Schedulers.io());
return launcherItems.mergeWith(networkItems);
}
private Observable<AutoCompleteServiceResult> searchForLauncherItems(
private Observable<SuggestionsResult> searchForLauncherItems(
CharSequence charSequence) {
String query = charSequence.toString().toLowerCase();
AutoCompleteServiceResult autoCompleteServiceResult = new AutoCompleteServiceResult(
SuggestionsResult suggestionsResult = new SuggestionsResult(
query);
List<LauncherItem> launcherItems = new ArrayList<>();
pages.parallelStream().forEach(gridLayout -> {
......@@ -1458,41 +1457,21 @@ public class LauncherActivity extends AppCompatActivity implements
));
if (launcherItems.size() > 4) {
autoCompleteServiceResult.setLauncherItems(launcherItems.subList(0, 4));
suggestionsResult.setLauncherItems(launcherItems.subList(0, 4));
} else {
autoCompleteServiceResult.setLauncherItems(launcherItems);
suggestionsResult.setLauncherItems(launcherItems);
}
return Observable.just(autoCompleteServiceResult)
return Observable.just(suggestionsResult)
.onErrorReturn(throwable -> {
autoCompleteServiceResult.setLauncherItems(new ArrayList<>());
return autoCompleteServiceResult;
suggestionsResult.setLauncherItems(new ArrayList<>());
return suggestionsResult;
});
}
private Observable<AutoCompleteServiceResult> searchForNetworkItems(CharSequence charSequence) {
AutoCompleteService autoCompleteService = RetrofitService.getInstance(
"https://duckduckgo.com").create(AutoCompleteService.class);
private Observable<SuggestionsResult> searchForNetworkItems(CharSequence charSequence) {
String query = charSequence.toString().toLowerCase(Locale.getDefault()).trim();
if (autoCompleteService != null) {
return autoCompleteService.query(query)
.retryWhen(errors -> errors.flatMap(error -> {
// For IOExceptions, we retry
if (error instanceof IOException) {
return Observable.just(null);
}
// For anything else, don't retry
return Observable.error(error);
}))
.onErrorReturn(throwable -> new ArrayList<>())
.map(autoCompleteServiceRawResults -> {
AutoCompleteServiceResult result = new AutoCompleteServiceResult(query);
result.setNetworkItems(autoCompleteServiceRawResults);
return result;
});
} else {
return Observable.just(new AutoCompleteServiceResult(query));
}
SuggestionProvider suggestionProvider = new SearchSuggestionUtil().getSuggestionProvider(this);
return suggestionProvider.query(query).toObservable();
}
@Override
......@@ -1504,8 +1483,8 @@ public class LauncherActivity extends AppCompatActivity implements
}
private void runSearch(String query) {
Uri uri = Uri.parse("https://spot.ecloud.global/?q=" + query);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
Intent intent = new Intent(Intent.ACTION_VIEW,
new SearchSuggestionUtil().getUriForQuery(this, query));
startActivity(intent);
}
......@@ -2847,7 +2826,7 @@ public class LauncherActivity extends AppCompatActivity implements
LauncherActivity.this.runOnUiThread(
() -> clearSuggestions.setVisibility(GONE));
return Observable.just(
new AutoCompleteServiceResult(charSequence));
new SuggestionsResult(charSequence));
}
})
.subscribeOn(Schedulers.io())
......
......@@ -5,16 +5,15 @@ import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
import foundation.e.blisslauncher.R;
import foundation.e.blisslauncher.core.customviews.BlissFrameLayout;
import foundation.e.blisslauncher.core.database.model.LauncherItem;
import foundation.e.blisslauncher.features.suggestions.AutoCompleteAdapter;
import foundation.e.blisslauncher.features.suggestions.AutoCompleteServiceResult;
import foundation.e.blisslauncher.features.suggestions.SuggestionsResult;
import io.reactivex.observers.DisposableObserver;
public class SearchInputDisposableObserver extends DisposableObserver<AutoCompleteServiceResult> {
public class SearchInputDisposableObserver extends DisposableObserver<SuggestionsResult> {
private AutoCompleteAdapter networkSuggestionAdapter;
private LauncherActivity launcherActivity;
......@@ -27,25 +26,17 @@ public class SearchInputDisposableObserver extends DisposableObserver<AutoComple
}
@Override
public void onNext(AutoCompleteServiceResult autoCompleteServiceResults) {
if (autoCompleteServiceResults.type
== AutoCompleteServiceResult.TYPE_NETWORK_ITEM) {
List<String> suggestions = new ArrayList<>();
for (int i = 0;
i < (autoCompleteServiceResults.networkItems.size() > 5 ? 5
: autoCompleteServiceResults.networkItems.size());
i++) {
suggestions.add(
autoCompleteServiceResults.networkItems.get(i).getPhrase());
}
networkSuggestionAdapter.updateSuggestions(suggestions,
autoCompleteServiceResults.queryText);
} else if (autoCompleteServiceResults.type
== AutoCompleteServiceResult.TYPE_LAUNCHER_ITEM) {
public void onNext(SuggestionsResult suggestionsResults) {
if (suggestionsResults.type
== SuggestionsResult.TYPE_NETWORK_ITEM) {
networkSuggestionAdapter.updateSuggestions(suggestionsResults.getNetworkItems(),
suggestionsResults.queryText);
} else if (suggestionsResults.type
== SuggestionsResult.TYPE_LAUNCHER_ITEM) {
((ViewGroup)appSuggestionsViewGroup.findViewById(R.id.suggestedAppGrid)).removeAllViews();
appSuggestionsViewGroup.findViewById(R.id.openUsageAccessSettings).setVisibility(View.GONE);
appSuggestionsViewGroup.findViewById(R.id.suggestedAppGrid).setVisibility(View.VISIBLE);
for (LauncherItem launcherItem : autoCompleteServiceResults
for (LauncherItem launcherItem : suggestionsResults
.getLauncherItems()) {
BlissFrameLayout blissFrameLayout = launcherActivity.prepareSuggestedApp(
launcherItem);
......@@ -54,7 +45,7 @@ public class SearchInputDisposableObserver extends DisposableObserver<AutoComple
} else {
launcherActivity.refreshSuggestedApps(appSuggestionsViewGroup,true);
networkSuggestionAdapter.updateSuggestions(new ArrayList<>(),
autoCompleteServiceResults.queryText);
suggestionsResults.queryText);
}
}
......
package foundation.e.blisslauncher.features.suggestions;
import java.io.IOException;
import java.util.ArrayList;
import foundation.e.blisslauncher.core.network.RetrofitService;
import foundation.e.blisslauncher.core.network.duckduckgo.DuckDuckGoResult;
import foundation.e.blisslauncher.core.network.duckduckgo.DuckDuckGoSuggestionService;
import io.reactivex.Observable;
import io.reactivex.Single;
public class DuckDuckGoProvider implements SuggestionProvider {
private DuckDuckGoSuggestionService getSuggestionService() {
String URL = "https://duckduckgo.com";
return RetrofitService.getInstance(
URL).create(DuckDuckGoSuggestionService.class);
}
@Override
public Single<SuggestionsResult> query(String query) {
return getSuggestionService().query(query)
.retryWhen(errors -> errors.flatMap(error -> {
// For IOExceptions, we retry
if (error instanceof IOException) {
return Observable.just(null);
}
// For anything else, don't retry
return Observable.error(error);
}))
.onErrorReturn(throwable -> new ArrayList<>())
.flatMapIterable(duckDuckGoResults -> duckDuckGoResults)
.take(5)
.map(DuckDuckGoResult::getPhrase)
.toList()
.map(suggestions -> {
SuggestionsResult suggestionsResult =
new SuggestionsResult(query);
suggestionsResult.setNetworkItems(suggestions);
return suggestionsResult;
});
}
}
package foundation.e.blisslauncher.features.suggestions;
import java.io.IOException;
import foundation.e.blisslauncher.core.network.RetrofitService;
import foundation.e.blisslauncher.core.network.qwant.QwantItem;
import foundation.e.blisslauncher.core.network.qwant.QwantResult;
import foundation.e.blisslauncher.core.network.qwant.QwantSuggestionService;
import io.reactivex.Observable;
import io.reactivex.Single;
public class QwantProvider implements SuggestionProvider {
private QwantSuggestionService getSuggestionService() {
String URL = "https://api.qwant.com";
return RetrofitService.getInstance(
URL).create(QwantSuggestionService.class);
}
@Override
public Single<SuggestionsResult> query(String query) {
return getSuggestionService().query(query)
.retryWhen(errors -> errors.flatMap(error -> {
// For IOExceptions, we retry
if (error instanceof IOException) {
return Observable.just(new QwantResult());
}
// For anything else, don't retry
return Observable.error(error);
}))
.filter(qwantResult -> qwantResult.getStatus().equals("success"))
.flatMapIterable(qwantResult -> qwantResult.getData().getItems())
.take(5)
.map(QwantItem::getValue)
.toList()
.map(suggestions -> {
SuggestionsResult suggestionsResult =
new SuggestionsResult(query);
suggestionsResult.setNetworkItems(suggestions);
return suggestionsResult;
});
}
}
package foundation.e.blisslauncher.features.suggestions;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
public class SearchSuggestionUtil {
public SuggestionProvider getSuggestionProvider(Context context) {
String defaultSearchEngine = defaultSearchEngine(context);
if (defaultSearchEngine != null && defaultSearchEngine.length() > 0) {
defaultSearchEngine = defaultSearchEngine.toLowerCase();
if (defaultSearchEngine.contains("qwant")) {
return new QwantProvider();
} else {
return new DuckDuckGoProvider();
}
} else {
return new DuckDuckGoProvider();
}
}
public Uri getUriForQuery(Context context, String query) {
String defaultSearchEngine = defaultSearchEngine(context);
if (defaultSearchEngine != null && defaultSearchEngine.length() > 0) {
defaultSearchEngine = defaultSearchEngine.toLowerCase();
if (defaultSearchEngine.contains("qwant")) {
return Uri.parse("https://www.qwant.com/?q=" + query);
} else if (defaultSearchEngine.contains("duckduckgo")) {
return Uri.parse("https://duckduckgo.com/?q=" + query);
} else {
return Uri.parse("https://spot.ecloud.global/?q=" + query);
}
} else {
return Uri.parse("https://spot.ecloud.global/?q=" + query);
}
}
private String defaultSearchEngine(Context context) {
ContentResolver contentResolver = context.getContentResolver();
Uri uri = Uri.parse("content://foundation.e.browser.provider").buildUpon().appendPath(
"search_engine").build();
Cursor cursor = contentResolver.query(uri, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
return cursor.getString(0);
} else {
return "";
}
}
}
package foundation.e.blisslauncher.features.suggestions;
import io.reactivex.Single;
public interface SuggestionProvider {
Single<SuggestionsResult> query(String query);
}
......@@ -4,27 +4,27 @@ import java.util.List;
import foundation.e.blisslauncher.core.database.model.LauncherItem;
public class AutoCompleteServiceResult {
public class SuggestionsResult {
public static final int TYPE_LAUNCHER_ITEM = 567;
public static final int TYPE_NETWORK_ITEM = 568;
public List<AutoCompleteServiceRawResult> networkItems;
private List<String> networkItems;
private List<LauncherItem> launcherItems;
public String queryText;
public int type = -1;
public AutoCompleteServiceResult(String queryText) {
public SuggestionsResult(String queryText) {
this.queryText = queryText;
}
public List<AutoCompleteServiceRawResult> getNetworkItems() {
public List<String> getNetworkItems() {
return networkItems;
}
public void setNetworkItems(
List<AutoCompleteServiceRawResult> networkItems) {
List<String> networkItems) {
this.networkItems = networkItems;
this.type = TYPE_NETWORK_ITEM;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment