diff --git a/F-Droid/AndroidManifest.xml b/F-Droid/AndroidManifest.xml index 6deda93e0..0f1036114 100644 --- a/F-Droid/AndroidManifest.xml +++ b/F-Droid/AndroidManifest.xml @@ -100,7 +100,7 @@ + android:value=".FDroid" /> + + + + + + @@ -388,25 +396,6 @@ - - - - - - - - - diff --git a/F-Droid/res/layout/available_app_list.xml b/F-Droid/res/layout/available_app_list.xml index 1ff394163..e1b35d157 100644 --- a/F-Droid/res/layout/available_app_list.xml +++ b/F-Droid/res/layout/available_app_list.xml @@ -4,27 +4,35 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="wrap_content" + android:id="@+id/category_wrapper" + android:layout_alignParentTop="true"> - + + + + + + android:layout_below="@id/category_wrapper" /> diff --git a/F-Droid/src/org/fdroid/fdroid/FDroid.java b/F-Droid/src/org/fdroid/fdroid/FDroid.java index d5eda5c4b..4a41f1b4b 100644 --- a/F-Droid/src/org/fdroid/fdroid/FDroid.java +++ b/F-Droid/src/org/fdroid/fdroid/FDroid.java @@ -29,10 +29,12 @@ import android.content.res.Configuration; import android.database.ContentObserver; import android.net.Uri; import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.view.MenuItemCompat; import android.support.v4.view.ViewPager; -import android.support.v7.app.ActionBarActivity; import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.SearchView; import android.text.TextUtils; import android.view.LayoutInflater; @@ -43,6 +45,7 @@ import android.widget.TextView; import android.widget.Toast; import org.fdroid.fdroid.compat.TabManager; +import org.fdroid.fdroid.compat.UriCompat; import org.fdroid.fdroid.data.AppProvider; import org.fdroid.fdroid.data.NewRepoConfig; import org.fdroid.fdroid.privileged.install.InstallExtensionDialogActivity; @@ -50,7 +53,7 @@ import org.fdroid.fdroid.views.AppListFragmentPagerAdapter; import org.fdroid.fdroid.views.ManageReposActivity; import org.fdroid.fdroid.views.swap.SwapWorkflowActivity; -public class FDroid extends ActionBarActivity { +public class FDroid extends AppCompatActivity implements SearchView.OnQueryTextListener { private static final String TAG = "FDroid"; @@ -66,8 +69,17 @@ public class FDroid extends ActionBarActivity { private ViewPager viewPager; + @Nullable private TabManager tabManager; + private AppListFragmentPagerAdapter adapter; + + @Nullable + private MenuItem searchMenuItem; + + @Nullable + private String pendingSearchQuery; + @Override protected void onCreate(Bundle savedInstanceState) { @@ -84,10 +96,7 @@ public class FDroid extends ActionBarActivity { setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); Intent intent = getIntent(); - - // If the intent can be handled via AppDetails or SearchResults, it - // will call finish() and the rest of the code won't execute - handleIntent(intent); + handleSearchOrAppViewIntent(intent); if (intent.hasExtra(EXTRA_TAB_UPDATE)) { boolean showUpdateTab = intent.getBooleanExtra(EXTRA_TAB_UPDATE, false); @@ -109,6 +118,18 @@ public class FDroid extends ActionBarActivity { // } } + private void performSearch(String query) { + if (searchMenuItem == null) { + // Store this for later when we do actually have a search menu ready to use. + pendingSearchQuery = query; + return; + } + + SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem); + MenuItemCompat.expandActionView(searchMenuItem); + searchView.setQuery(query, true); + } + @Override protected void onResume() { super.onResume(); @@ -117,11 +138,24 @@ public class FDroid extends ActionBarActivity { checkForAddRepoIntent(); } - private void handleIntent(Intent intent) { + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + handleSearchOrAppViewIntent(intent); + } + + private void handleSearchOrAppViewIntent(Intent intent) { + if (Intent.ACTION_SEARCH.equals(intent.getAction())) { + String query = intent.getStringExtra(SearchManager.QUERY); + performSearch(query); + return; + } + final Uri data = intent.getData(); if (data == null) { return; } + final String scheme = data.getScheme(); final String path = data.getPath(); String appId = null; @@ -133,11 +167,14 @@ public class FDroid extends ActionBarActivity { } switch (host) { case "f-droid.org": - // http://f-droid.org/app/app.id if (path.startsWith("/repository/browse")) { + // http://f-droid.org/repository/browse?fdfilter=search+query + query = UriCompat.getQueryParameter(data, "fdfilter"); + // http://f-droid.org/repository/browse?fdid=app.id - appId = data.getQueryParameter("fdid"); + appId = UriCompat.getQueryParameter(data, "fdid"); } else if (path.startsWith("/app")) { + // http://f-droid.org/app/app.id appId = data.getLastPathSegment(); if ("app".equals(appId)) { appId = null; @@ -146,28 +183,28 @@ public class FDroid extends ActionBarActivity { break; case "details": // market://details?id=app.id - appId = data.getQueryParameter("id"); + appId = UriCompat.getQueryParameter(data, "id"); break; case "search": // market://search?q=query - query = data.getQueryParameter("q"); + query = UriCompat.getQueryParameter(data, "q"); break; case "play.google.com": if (path.startsWith("/store/apps/details")) { // http://play.google.com/store/apps/details?id=app.id - appId = data.getQueryParameter("id"); + appId = UriCompat.getQueryParameter(data, "id"); } else if (path.startsWith("/store/search")) { // http://play.google.com/store/search?q=foo - query = data.getQueryParameter("q"); + query = UriCompat.getQueryParameter(data, "q"); } break; case "apps": case "amazon.com": case "www.amazon.com": // amzn://apps/android?p=app.id - // http://amazon.com/gp/mas/dl/android?p=app.id - appId = data.getQueryParameter("p"); - query = data.getQueryParameter("s"); + // http://amazon.com/gp/mas/dl/android?s=app.id + appId = UriCompat.getQueryParameter(data, "p"); + query = UriCompat.getQueryParameter(data, "s"); break; } } else if ("fdroid.app".equals(scheme)) { @@ -188,20 +225,14 @@ public class FDroid extends ActionBarActivity { query = query.split(":")[1]; } - Intent call = null; if (!TextUtils.isEmpty(appId)) { Utils.debugLog(TAG, "FDroid launched via app link for '" + appId + "'"); - call = new Intent(this, AppDetails.class); - call.putExtra(AppDetails.EXTRA_APPID, appId); + Intent intentToInvoke = new Intent(this, AppDetails.class); + intentToInvoke.putExtra(AppDetails.EXTRA_APPID, appId); + startActivity(intentToInvoke); } else if (!TextUtils.isEmpty(query)) { Utils.debugLog(TAG, "FDroid launched via search link for '" + query + "'"); - call = new Intent(this, SearchResults.class); - call.setAction(Intent.ACTION_SEARCH); - call.putExtra(SearchManager.QUERY, query); - } - if (call != null) { - startActivity(call); - finish(); + performSearch(query); } } @@ -243,11 +274,19 @@ public class FDroid extends ActionBarActivity { } SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); - MenuItem searchItem = menu.findItem(R.id.action_search); - SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); + searchMenuItem = menu.findItem(R.id.action_search); + SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); // LayoutParams.MATCH_PARENT does not work, use a big value instead searchView.setMaxWidth(1000000); + searchView.setOnQueryTextListener(this); + + // If we were asked to execute a search before getting around to building the options + // menu, then we should deal with that now that the options menu is all sorted out. + if (pendingSearchQuery != null) { + performSearch(pendingSearchQuery); + pendingSearchQuery = null; + } return super.onCreateOptionsMenu(menu); } @@ -335,8 +374,8 @@ public class FDroid extends ActionBarActivity { private void createViews() { viewPager = (ViewPager) findViewById(R.id.main_pager); - AppListFragmentPagerAdapter viewPagerAdapter = new AppListFragmentPagerAdapter(this); - viewPager.setAdapter(viewPagerAdapter); + adapter = new AppListFragmentPagerAdapter(this); + viewPager.setAdapter(adapter); viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { @@ -345,6 +384,7 @@ public class FDroid extends ActionBarActivity { }); } + @NonNull private TabManager getTabManager() { if (tabManager == null) { tabManager = new TabManager(this, viewPager); @@ -363,6 +403,19 @@ public class FDroid extends ActionBarActivity { nMgr.cancel(id); } + @Override + public boolean onQueryTextSubmit(String query) { + // Do nothing, because we respond to the query being changed as it is updated + // via onQueryTextChange(...) + return true; + } + + @Override + public boolean onQueryTextChange(String newText) { + adapter.updateSearchQuery(newText); + return true; + } + private class AppObserver extends ContentObserver { AppObserver() { diff --git a/F-Droid/src/org/fdroid/fdroid/compat/UriCompat.java b/F-Droid/src/org/fdroid/fdroid/compat/UriCompat.java new file mode 100644 index 000000000..90ffff0ca --- /dev/null +++ b/F-Droid/src/org/fdroid/fdroid/compat/UriCompat.java @@ -0,0 +1,21 @@ +package org.fdroid.fdroid.compat; + +import android.net.Uri; +import android.os.Build; + +public class UriCompat { + + /** + * Uri#getQueryParameter(String) has the following warning: + * + * > Prior to Ice Cream Sandwich, this decoded the '+' character as '+' rather than ' '. + */ + public static String getQueryParameter(Uri uri, String key) { + String value = uri.getQueryParameter(key); + if (value != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + value = value.replaceAll("\\+", " "); + } + return value; + } + +} diff --git a/F-Droid/src/org/fdroid/fdroid/data/AppProvider.java b/F-Droid/src/org/fdroid/fdroid/data/AppProvider.java index 79019be56..e30fcfb61 100644 --- a/F-Droid/src/org/fdroid/fdroid/data/AppProvider.java +++ b/F-Droid/src/org/fdroid/fdroid/data/AppProvider.java @@ -425,6 +425,8 @@ public class AppProvider extends FDroidProvider { private static final String PATH_INSTALLED = "installed"; private static final String PATH_CAN_UPDATE = "canUpdate"; private static final String PATH_SEARCH = "search"; + private static final String PATH_SEARCH_INSTALLED = "searchInstalled"; + private static final String PATH_SEARCH_CAN_UPDATE = "searchCanUpdate"; private static final String PATH_SEARCH_REPO = "searchRepo"; private static final String PATH_NO_APKS = "noApks"; private static final String PATH_APPS = "apps"; @@ -435,18 +437,20 @@ public class AppProvider extends FDroidProvider { private static final String PATH_CALC_APP_DETAILS_FROM_INDEX = "calcDetailsFromIndex"; private static final String PATH_REPO = "repo"; - private static final int CAN_UPDATE = CODE_SINGLE + 1; - private static final int INSTALLED = CAN_UPDATE + 1; - private static final int SEARCH = INSTALLED + 1; - private static final int NO_APKS = SEARCH + 1; - private static final int APPS = NO_APKS + 1; + private static final int CAN_UPDATE = CODE_SINGLE + 1; + private static final int INSTALLED = CAN_UPDATE + 1; + private static final int SEARCH = INSTALLED + 1; + private static final int NO_APKS = SEARCH + 1; + private static final int APPS = NO_APKS + 1; private static final int RECENTLY_UPDATED = APPS + 1; - private static final int NEWLY_ADDED = RECENTLY_UPDATED + 1; - private static final int CATEGORY = NEWLY_ADDED + 1; - private static final int IGNORED = CATEGORY + 1; + private static final int NEWLY_ADDED = RECENTLY_UPDATED + 1; + private static final int CATEGORY = NEWLY_ADDED + 1; + private static final int IGNORED = CATEGORY + 1; private static final int CALC_APP_DETAILS_FROM_INDEX = IGNORED + 1; - private static final int REPO = CALC_APP_DETAILS_FROM_INDEX + 1; - private static final int SEARCH_REPO = REPO + 1; + private static final int REPO = CALC_APP_DETAILS_FROM_INDEX + 1; + private static final int SEARCH_REPO = REPO + 1; + private static final int SEARCH_INSTALLED = SEARCH_REPO + 1; + private static final int SEARCH_CAN_UPDATE = SEARCH_INSTALLED + 1; static { matcher.addURI(getAuthority(), null, CODE_LIST); @@ -456,6 +460,8 @@ public class AppProvider extends FDroidProvider { matcher.addURI(getAuthority(), PATH_NEWLY_ADDED, NEWLY_ADDED); matcher.addURI(getAuthority(), PATH_CATEGORY + "/*", CATEGORY); matcher.addURI(getAuthority(), PATH_SEARCH + "/*", SEARCH); + matcher.addURI(getAuthority(), PATH_SEARCH_INSTALLED + "/*", SEARCH_INSTALLED); + matcher.addURI(getAuthority(), PATH_SEARCH_CAN_UPDATE + "/*", SEARCH_CAN_UPDATE); matcher.addURI(getAuthority(), PATH_SEARCH_REPO + "/*/*", SEARCH_REPO); matcher.addURI(getAuthority(), PATH_REPO + "/#", REPO); matcher.addURI(getAuthority(), PATH_CAN_UPDATE, CAN_UPDATE); @@ -536,7 +542,23 @@ public class AppProvider extends FDroidProvider { public static Uri getSearchUri(String query) { return getContentUri().buildUpon() .appendPath(PATH_SEARCH) - .appendPath(query) + .appendEncodedPath(query) + .build(); + } + + public static Uri getSearchInstalledUri(String query) { + return getContentUri() + .buildUpon() + .appendPath(PATH_SEARCH_INSTALLED) + .appendEncodedPath(query) + .build(); + } + + public static Uri getSearchCanUpdateUri(String query) { + return getContentUri() + .buildUpon() + .appendPath(PATH_SEARCH_CAN_UPDATE) + .appendEncodedPath(query) .build(); } @@ -544,7 +566,7 @@ public class AppProvider extends FDroidProvider { return getContentUri().buildUpon() .appendPath(PATH_SEARCH_REPO) .appendPath(repo.id + "") - .appendPath(query) + .appendEncodedPath(query) .build(); } @@ -597,7 +619,7 @@ public class AppProvider extends FDroidProvider { getTableName() + ".description", }; - // Remove duplicates, surround in % for case insensitive searching + // Remove duplicates, surround in % for wildcard searching final Set keywordSet = new HashSet<>(Arrays.asList(query.split("\\s"))); final String[] keywords = new String[keywordSet.size()]; int iKeyword = 0; @@ -735,6 +757,16 @@ public class AppProvider extends FDroidProvider { includeSwap = false; break; + case SEARCH_INSTALLED: + selection = querySearch(uri.getLastPathSegment()).add(queryInstalled()); + includeSwap = false; + break; + + case SEARCH_CAN_UPDATE: + selection = querySearch(uri.getLastPathSegment()).add(queryCanUpdate()); + includeSwap = false; + break; + case SEARCH_REPO: selection = selection.add(querySearch(uri.getPathSegments().get(2))); selection = selection.add(queryRepo(Long.parseLong(uri.getPathSegments().get(1)))); diff --git a/F-Droid/src/org/fdroid/fdroid/views/AppListFragmentPagerAdapter.java b/F-Droid/src/org/fdroid/fdroid/views/AppListFragmentPagerAdapter.java index 43ac7b81f..7ce790d3c 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/AppListFragmentPagerAdapter.java +++ b/F-Droid/src/org/fdroid/fdroid/views/AppListFragmentPagerAdapter.java @@ -1,5 +1,7 @@ package org.fdroid.fdroid.views; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentPagerAdapter; @@ -7,6 +9,7 @@ import org.fdroid.fdroid.FDroid; import org.fdroid.fdroid.R; import org.fdroid.fdroid.compat.TabManager; import org.fdroid.fdroid.data.AppProvider; +import org.fdroid.fdroid.views.fragments.AppListFragment; import org.fdroid.fdroid.views.fragments.AvailableAppsFragment; import org.fdroid.fdroid.views.fragments.CanUpdateAppsFragment; import org.fdroid.fdroid.views.fragments.InstalledAppsFragment; @@ -17,11 +20,19 @@ import org.fdroid.fdroid.views.fragments.InstalledAppsFragment; */ public class AppListFragmentPagerAdapter extends FragmentPagerAdapter { - private final FDroid parent; + @NonNull private final FDroid parent; - public AppListFragmentPagerAdapter(FDroid parent) { + @NonNull private final AppListFragment availableFragment; + @NonNull private final AppListFragment installedFragment; + @NonNull private final AppListFragment canUpdateFragment; + + public AppListFragmentPagerAdapter(@NonNull FDroid parent) { super(parent.getSupportFragmentManager()); this.parent = parent; + + availableFragment = new AvailableAppsFragment(); + installedFragment = new InstalledAppsFragment(); + canUpdateFragment = new CanUpdateAppsFragment(); } private String getInstalledTabTitle() { @@ -34,15 +45,21 @@ public class AppListFragmentPagerAdapter extends FragmentPagerAdapter { return parent.getString(R.string.tab_updates_count, updateCount); } + public void updateSearchQuery(@Nullable String query) { + availableFragment.updateSearchQuery(query); + installedFragment.updateSearchQuery(query); + canUpdateFragment.updateSearchQuery(query); + } + @Override public Fragment getItem(int i) { switch (i) { case TabManager.INDEX_AVAILABLE: - return new AvailableAppsFragment(); + return availableFragment; case TabManager.INDEX_INSTALLED: - return new InstalledAppsFragment(); + return installedFragment; default: - return new CanUpdateAppsFragment(); + return canUpdateFragment; } } diff --git a/F-Droid/src/org/fdroid/fdroid/views/fragments/AppListFragment.java b/F-Droid/src/org/fdroid/fdroid/views/fragments/AppListFragment.java index 401c14120..b6efa0f14 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/fragments/AppListFragment.java +++ b/F-Droid/src/org/fdroid/fdroid/views/fragments/AppListFragment.java @@ -6,10 +6,12 @@ import android.content.SharedPreferences; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.v4.app.ListFragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; +import android.text.TextUtils; import android.view.View; import android.widget.AdapterView; @@ -52,12 +54,36 @@ public abstract class AppListFragment extends ListFragment implements protected AppListAdapter appAdapter; + @Nullable private String searchQuery; + protected abstract AppListAdapter getAppListAdapter(); protected abstract String getFromTitle(); protected abstract Uri getDataUri(); + protected abstract Uri getDataUri(String query); + + /** + * Subclasses can choose to do different things based on when a user begins searching. + * For example, the "Available" tab chooses to hide its category spinner to make it clear + * that it is searching all apps, not the current category. + * NOTE: This will get called multiple times, every time the user changes the + * search query. + */ + protected void onSearch() { + // Do nothing by default. + } + + /** + * Alerts the child class that the user is no longer performing a search. + * This is triggered every time the search query is blank. + * @see AppListFragment#onSearch() + */ + protected void onSearchStopped() { + // Do nothing by default. + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); @@ -144,9 +170,30 @@ public abstract class AppListFragment extends ListFragment implements @Override public Loader onCreateLoader(int id, Bundle args) { - Uri uri = getDataUri(); + Uri uri = updateSearchStatus() ? getDataUri(searchQuery) : getDataUri(); return new CursorLoader( getActivity(), uri, APP_PROJECTION, null, null, APP_SORT); } + /** + * Notifies the subclass via {@link AppListFragment#onSearch()} and {@link AppListFragment#onSearchStopped()} + * about whether or not a search is taking place. + * @return True if a user is searching. + */ + private boolean updateSearchStatus() { + if (TextUtils.isEmpty(searchQuery)) { + onSearchStopped(); + return false; + } else { + onSearch(); + return true; + } + } + + public void updateSearchQuery(@Nullable String query) { + searchQuery = query; + if (isAdded()) { + getLoaderManager().restartLoader(0, null, this); + } + } } diff --git a/F-Droid/src/org/fdroid/fdroid/views/fragments/AvailableAppsFragment.java b/F-Droid/src/org/fdroid/fdroid/views/fragments/AvailableAppsFragment.java index ffb14c4e2..0b7aab7e5 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/fragments/AvailableAppsFragment.java +++ b/F-Droid/src/org/fdroid/fdroid/views/fragments/AvailableAppsFragment.java @@ -8,6 +8,7 @@ import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.v4.app.LoaderManager; import android.view.LayoutInflater; import android.view.View; @@ -37,6 +38,11 @@ public class AvailableAppsFragment extends AppListFragment implements private static String defaultCategory; private List categories; + + @Nullable + private View categoryWrapper; + + @Nullable private Spinner categorySpinner; private String currentCategory; private AppListAdapter adapter; @@ -147,6 +153,7 @@ public class AvailableAppsFragment extends AppListFragment implements public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.available_app_list, container, false); + categoryWrapper = view.findViewById(R.id.category_wrapper); setupCategorySpinner((Spinner) view.findViewById(R.id.category_spinner)); defaultCategory = AppProvider.Helper.getCategoryWhatsNew(getActivity()); @@ -164,6 +171,11 @@ public class AvailableAppsFragment extends AppListFragment implements return AppProvider.getCategoryUri(currentCategory); } + @Override + protected Uri getDataUri(String query) { + return AppProvider.getSearchUri(query); + } + private void setCurrentCategory(String category) { currentCategory = category; Utils.debugLog(TAG, "Category '" + currentCategory + "' selected."); @@ -175,15 +187,18 @@ public class AvailableAppsFragment extends AppListFragment implements super.onResume(); /* restore the saved Category Spinner position */ Activity activity = getActivity(); - SharedPreferences p = activity.getSharedPreferences(PREFERENCES_FILE, - Context.MODE_PRIVATE); + SharedPreferences p = activity.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE); currentCategory = p.getString(CATEGORY_KEY, defaultCategory); - for (int i = 0; i < categorySpinner.getCount(); i++) { - if (currentCategory.equals(categorySpinner.getItemAtPosition(i).toString())) { - categorySpinner.setSelection(i); - break; + + if (categorySpinner != null) { + for (int i = 0; i < categorySpinner.getCount(); i++) { + if (currentCategory.equals(categorySpinner.getItemAtPosition(i).toString())) { + categorySpinner.setSelection(i); + break; + } } } + setCurrentCategory(currentCategory); } @@ -197,4 +212,18 @@ public class AvailableAppsFragment extends AppListFragment implements e.putString(CATEGORY_KEY, currentCategory); e.commit(); } + + @Override + protected void onSearch() { + if (categoryWrapper != null) { + categoryWrapper.setVisibility(View.GONE); + } + } + + @Override + protected void onSearchStopped() { + if (categoryWrapper != null) { + categoryWrapper.setVisibility(View.VISIBLE); + } + } } diff --git a/F-Droid/src/org/fdroid/fdroid/views/fragments/CanUpdateAppsFragment.java b/F-Droid/src/org/fdroid/fdroid/views/fragments/CanUpdateAppsFragment.java index e767077b9..8b5954609 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/fragments/CanUpdateAppsFragment.java +++ b/F-Droid/src/org/fdroid/fdroid/views/fragments/CanUpdateAppsFragment.java @@ -28,6 +28,10 @@ public class CanUpdateAppsFragment extends AppListFragment { return AppProvider.getCanUpdateUri(); } + protected Uri getDataUri(String query) { + return AppProvider.getSearchCanUpdateUri(query); + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.can_update_app_list, container, false); diff --git a/F-Droid/src/org/fdroid/fdroid/views/fragments/InstalledAppsFragment.java b/F-Droid/src/org/fdroid/fdroid/views/fragments/InstalledAppsFragment.java index d5078b80f..7f7a77c01 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/fragments/InstalledAppsFragment.java +++ b/F-Droid/src/org/fdroid/fdroid/views/fragments/InstalledAppsFragment.java @@ -28,6 +28,10 @@ public class InstalledAppsFragment extends AppListFragment { return AppProvider.getInstalledUri(); } + protected Uri getDataUri(String query) { + return AppProvider.getSearchInstalledUri(query); + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.installed_app_list, container, false); diff --git a/F-Droid/tools/test-search-intents.sh b/F-Droid/tools/test-search-intents.sh new file mode 100755 index 000000000..172eaddde --- /dev/null +++ b/F-Droid/tools/test-search-intents.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +echo "A helper script to send all of the various intents that F-droid should be able to handle via ADB." +echo "Use this to ensure that things which should trigger searches, do trigger searches, and those which should bring up the app details screen, do bring it up." +echo "" + +function view { + DESCRIPTION=$1 + DATA=$2 + wait "$DESCRIPTION" + CMD="adb shell am start -a android.intent.action.VIEW -d $DATA" + $CMD + echo "" + sleep 1 +} + +function wait { + DESCRIPTION=$1 + echo "$DESCRIPTION [Y/n]" + + read -n 1 RESULT + + # Lower case the result. + RESULT=`echo "$RESULT" | tr '[:upper:]' '[:lower:]'` + + echo "" + + if [ "$RESULT" != 'y' ]; then + exit; + fi +} + +APP_TO_SHOW=org.fdroid.fdroid +SEARCH_QUERY=book+reader + +view "Search for '$SEARCH_QUERY' (fdroid web)" http://f-droid.org/repository/browse?fdfilter=$SEARCH_QUERY +view "Search for '$SEARCH_QUERY' (market)" market://search?q=$SEARCH_QUERY +view "Search for '$SEARCH_QUERY' (play)" http://play.google.com/store/search?q=$SEARCH_QUERY +view "Search for '$SEARCH_QUERY' (amazon)" http://amazon.com/gp/mas/dl/android?s=$SEARCH_QUERY +view "Search for '$SEARCH_QUERY' (fdroid)" fdroid.search:$SEARCH_QUERY +view "View '$APP_TO_SHOW' (fdroid web fdid)" http://f-droid.org/repository/browse?fdid=$APP_TO_SHOW +view "View '$APP_TO_SHOW' (fdroid web /app/ path)" http://f-droid.org/app/$APP_TO_SHOW +view "View '$APP_TO_SHOW' (market)" market://details?id=$APP_TO_SHOW +view "View '$APP_TO_SHOW' (play)" http://play.google.com/store/apps/details?id=$APP_TO_SHOW +view "View '$APP_TO_SHOW' (amazon)" amzn://apps/android?p=$APP_TO_SHOW +view "View '$APP_TO_SHOW' (fdroid)" fdroid.app:$APP_TO_SHOW