Don't show swap apps in the main list of apps.

Achieve this by joining the fdroid_app table onto fdroid_apk and then
fdroid_repo, then checking if fdroid_repo.isSwap is 1.
This commit is contained in:
Peter Serwylo 2015-03-18 08:09:57 +11:00
parent 85300331e0
commit da566b44ce
5 changed files with 99 additions and 9 deletions

View File

@ -262,7 +262,13 @@ public class AppProvider extends FDroidProvider {
@Override
protected String getRequiredTables() {
return DBHelper.TABLE_APP;
final String app = DBHelper.TABLE_APP;
final String apk = DBHelper.TABLE_APK;
final String repo = DBHelper.TABLE_REPO;
return app +
" LEFT JOIN " + apk + " ON ( " + apk + ".id = " + app + ".id ) " +
" LEFT JOIN " + repo + " ON ( " + apk + ".repo = " + repo + "._id )";
}
@Override
@ -270,6 +276,11 @@ public class AppProvider extends FDroidProvider {
return fieldCount() == 1 && categoryFieldAdded;
}
@Override
protected String groupBy() {
return DBHelper.TABLE_APP + ".id";
}
public void addSelection(AppQuerySelection selection) {
addSelection(selection.getSelection());
if (selection.naturalJoinToInstalled()) {
@ -372,6 +383,7 @@ public class AppProvider extends FDroidProvider {
private static final String PATH_CATEGORY = "category";
private static final String PATH_IGNORED = "ignored";
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;
@ -383,6 +395,7 @@ public class AppProvider extends FDroidProvider {
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;
static {
matcher.addURI(getAuthority(), null, CODE_LIST);
@ -392,6 +405,7 @@ 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_REPO + "/#", REPO);
matcher.addURI(getAuthority(), PATH_CAN_UPDATE, CAN_UPDATE);
matcher.addURI(getAuthority(), PATH_INSTALLED, INSTALLED);
matcher.addURI(getAuthority(), PATH_NO_APKS, NO_APKS);
@ -438,6 +452,13 @@ public class AppProvider extends FDroidProvider {
return Uri.withAppendedPath(getContentUri(), PATH_CAN_UPDATE);
}
public static Uri getRepoUri(Repo repo) {
return getContentUri().buildUpon()
.appendPath(PATH_REPO)
.appendPath(String.valueOf(repo.id))
.build();
}
public static Uri getContentUri(List<App> apps) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < apps.size(); i ++) {
@ -494,6 +515,12 @@ public class AppProvider extends FDroidProvider {
return new AppQuerySelection(where).requireNaturalInstalledTable();
}
private AppQuerySelection queryRepo(long repoId) {
String selection = " fdroid_apk.repo = ? ";
String[] args = { String.valueOf(repoId) };
return new AppQuerySelection(selection, args);
}
private AppQuerySelection queryInstalled() {
return new AppQuerySelection().requireNaturalInstalledTable();
}
@ -555,6 +582,14 @@ public class AppProvider extends FDroidProvider {
return new AppQuerySelection(selection);
}
private AppQuerySelection queryExcludeSwap() {
// fdroid_repo will have null fields if the LEFT JOIN didn't resolve, e.g. due to there
// being no apks for the app in the result set. In that case, we can't tell if it is from
// a swap repo or not.
String selection = " fdroid_repo.isSwap = 0 OR fdroid_repo.isSwap is null ";
return new AppQuerySelection(selection);
}
private AppQuerySelection queryNewlyAdded() {
String selection = "fdroid_app.added > ?";
String[] args = { Utils.DATE_FORMAT.format(Preferences.get().calcMaxHistory()) };
@ -599,11 +634,13 @@ public class AppProvider extends FDroidProvider {
public Cursor query(Uri uri, String[] projection, String customSelection, String[] selectionArgs, String sortOrder) {
Query query = new Query();
AppQuerySelection selection = new AppQuerySelection(customSelection, selectionArgs);
boolean includeSwap = false;
switch (matcher.match(uri)) {
case CODE_LIST:
break;
case CODE_SINGLE:
includeSwap = true;
selection = selection.add(querySingle(uri.getLastPathSegment()));
break;
@ -611,6 +648,11 @@ public class AppProvider extends FDroidProvider {
selection = selection.add(queryCanUpdate());
break;
case REPO:
includeSwap = true;
selection = selection.add(queryRepo(Long.parseLong(uri.getLastPathSegment())));
break;
case INSTALLED:
selection = selection.add(queryInstalled());
break;
@ -650,6 +692,10 @@ public class AppProvider extends FDroidProvider {
throw new UnsupportedOperationException("Invalid URI for app content provider: " + uri);
}
if (!includeSwap) {
selection = selection.add(queryExcludeSwap());
}
if (AppProvider.DataColumns.NAME.equals(sortOrder)) {
sortOrder = " lower( fdroid_app." + sortOrder + " ) ";
}

View File

@ -28,6 +28,10 @@ abstract class QueryBuilder {
return false;
}
protected String groupBy() {
return null;
}
protected void appendField(String field) {
appendField(field, null, null);
}
@ -85,6 +89,10 @@ abstract class QueryBuilder {
.append(')');
}
private String distinctSql() {
return isDistinct() ? " DISTINCT " : "";
}
private String fieldsSql() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < fields.size(); i ++) {
@ -104,12 +112,15 @@ abstract class QueryBuilder {
return orderBy != null ? " ORDER BY " + orderBy : "";
}
private String groupBySql() {
return groupBy() != null ? " GROUP BY " + groupBy() : "";
}
private String tablesSql() {
return tables.toString();
}
public String toString() {
String distinct = isDistinct() ? " DISTINCT " : "";
return "SELECT " + distinct + fieldsSql() + " FROM " + tablesSql() + whereSql() + orderBySql();
return "SELECT " + distinctSql() + fieldsSql() + " FROM " + tablesSql() + whereSql() + groupBySql() + orderBySql();
}
}

View File

@ -5,6 +5,7 @@ import android.content.ContentValues;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
@ -24,6 +25,9 @@ public class ConfirmReceiveSwapFragment extends Fragment implements ProgressList
private NewRepoConfig newRepoConfig;
@Nullable
private Repo repo;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -64,8 +68,8 @@ public class ConfirmReceiveSwapFragment extends Fragment implements ProgressList
}
private void confirm() {
Repo repo = ensureRepoExists();
UpdateService.updateRepoNow(repo.address, getActivity()).setListener(this);
this.repo = ensureRepoExists();
UpdateService.updateRepoNow(this.repo.address, getActivity()).setListener(this);
}
@NonNull
@ -104,7 +108,7 @@ public class ConfirmReceiveSwapFragment extends Fragment implements ProgressList
if (event.type.equals(UpdateService.EVENT_COMPLETE_AND_SAME) ||
event.type.equals(UpdateService.EVENT_COMPLETE_WITH_CHANGES)) {
((ConnectSwapActivity)getActivity()).onRepoUpdated();
((ConnectSwapActivity)getActivity()).onRepoUpdated(repo);
/*Intent intent = new Intent();
intent.putExtra("category", newRepoConfig.getHost()); // TODO: Load repo from database to get proper name. This is what the category we want to select will be called.
getActivity().setResult(Activity.RESULT_OK, intent);

View File

@ -5,10 +5,11 @@ import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import org.fdroid.fdroid.data.Repo;
public class ConnectSwapActivity extends FragmentActivity {
private static final String STATE_CONFIRM = "startSwap";
private static final String STATE_APP_LIST = "swapAppList";
@Override
public void onCreate(Bundle savedInstanceState) {
@ -42,9 +43,10 @@ public class ConnectSwapActivity extends FragmentActivity {
return lastFragment.getName();
}
public void onRepoUpdated() {
public void onRepoUpdated(Repo repo) {
Intent intent = new Intent(this, SwapAppListActivity.class);
intent.putExtra(SwapAppListActivity.EXTRA_REPO_ADDRESS, repo.address);
startActivity(intent);
}

View File

@ -1,5 +1,6 @@
package org.fdroid.fdroid.views.swap;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@ -9,12 +10,18 @@ import android.support.v7.app.ActionBarActivity;
import org.fdroid.fdroid.AppDetails;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.data.AppProvider;
import org.fdroid.fdroid.data.Repo;
import org.fdroid.fdroid.data.RepoProvider;
import org.fdroid.fdroid.views.AppListAdapter;
import org.fdroid.fdroid.views.AvailableAppListAdapter;
import org.fdroid.fdroid.views.fragments.AppListFragment;
public class SwapAppListActivity extends ActionBarActivity {
public static String EXTRA_REPO_ADDRESS = "repoAddress";
private Repo repo;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -36,8 +43,28 @@ public class SwapAppListActivity extends ActionBarActivity {
}
@Override
protected void onResume() {
super.onResume();
String repoAddress = getIntent().getStringExtra(EXTRA_REPO_ADDRESS);
repo = RepoProvider.Helper.findByAddress(this, repoAddress);
}
public Repo getRepo() {
return repo;
}
public static class SwapAppListFragment extends AppListFragment {
private Repo repo;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
repo = ((SwapAppListActivity)activity).getRepo();
}
@Override
protected int getHeaderLayout() {
return R.layout.swap_success_header;
@ -61,7 +88,7 @@ public class SwapAppListActivity extends ActionBarActivity {
@Override
protected Uri getDataUri() {
return AppProvider.getCategoryUri("LocalRepo");
return AppProvider.getRepoUri(repo);
}
}