filter out unknown linked ids

This commit is contained in:
Vincent Breitmoser
2015-03-10 03:30:20 +01:00
parent f069d9814d
commit deafe946fd
3 changed files with 116 additions and 22 deletions

View File

@@ -46,6 +46,7 @@ import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment;
import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment;
import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment.OnIdentityLoadedListener;
import org.sufficientlysecure.keychain.util.FilterCursorWrapper;
import org.sufficientlysecure.keychain.util.Log;
public class ViewKeyFragment extends LoaderFragment implements
@@ -218,18 +219,18 @@ public class ViewKeyFragment extends LoaderFragment implements
}
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
switch (loader.getId()) {
case LOADER_ID_USER_IDS: {
mUserIdsAdapter.swapCursor(data);
mUserIdsAdapter.swapCursor(cursor);
break;
}
case LOADER_ID_LINKED_IDS: {
mLinkedIdsCard.setVisibility(data.getCount() > 0 ? View.VISIBLE : View.GONE);
mLinkedIdsAdapter.swapCursor(data);
mLinkedIdsCard.setVisibility(cursor.getCount() > 0 ? View.VISIBLE : View.GONE);
mLinkedIdsAdapter.swapCursor(cursor);
break;
}
}

View File

@@ -22,7 +22,6 @@ import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.support.v4.app.Fragment;
import android.support.v4.content.CursorLoader;
import android.util.Log;
import android.view.LayoutInflater;
@@ -35,12 +34,12 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.linked.LinkedIdentity;
import org.sufficientlysecure.keychain.pgp.linked.RawLinkedIdentity;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import org.sufficientlysecure.keychain.util.FilterCursorWrapper;
import java.io.IOException;
import java.util.WeakHashMap;
@@ -57,6 +56,23 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {
mShowCertification = showCertification;
}
@Override
public Cursor swapCursor(Cursor cursor) {
if (cursor == null) {
return super.swapCursor(null);
}
Cursor filteredCursor = new FilterCursorWrapper(cursor) {
@Override
public boolean isVisible(Cursor cursor) {
RawLinkedIdentity id = getItemAtPosition(cursor);
return id instanceof LinkedIdentity;
}
};
return super.swapCursor(filteredCursor);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
@@ -83,25 +99,26 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {
holder.vVerified.setVisibility(View.GONE);
}
RawLinkedIdentity id = getItem(cursor.getPosition());
RawLinkedIdentity id = getItemAtPosition(cursor);
holder.setData(mContext, id);
}
@Override
public RawLinkedIdentity getItem(int position) {
RawLinkedIdentity ret = mLinkedIdentityCache.get(position);
public RawLinkedIdentity getItemAtPosition(Cursor cursor) {
int rank = cursor.getInt(INDEX_RANK);
Log.d(Constants.TAG, "requested rank: " + rank);
RawLinkedIdentity ret = mLinkedIdentityCache.get(rank);
if (ret != null) {
Log.d(Constants.TAG, "cached!");
return ret;
}
Log.d(Constants.TAG, "not cached!");
Cursor c = getCursor();
c.moveToPosition(position);
byte[] data = c.getBlob(INDEX_ATTRIBUTE_DATA);
try {
byte[] data = cursor.getBlob(INDEX_ATTRIBUTE_DATA);
ret = LinkedIdentity.fromAttributeData(data);
mLinkedIdentityCache.put(position, ret);
mLinkedIdentityCache.put(rank, ret);
return ret;
} catch (IOException e) {
Log.e(Constants.TAG, "could not read linked identity subpacket data", e);
@@ -109,6 +126,13 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {
}
}
@Override
public RawLinkedIdentity getItem(int position) {
Cursor cursor = getCursor();
cursor.moveToPosition(position);
return getItemAtPosition(cursor);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = mInflater.inflate(R.layout.linked_id_item, null);
@@ -128,7 +152,6 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {
public LinkedIdViewFragment getLinkedIdFragment(Uri baseUri,
int position, byte[] fingerprint) throws IOException {
Cursor c = getCursor();
c.moveToPosition(position);
int rank = c.getInt(UserIdsAdapter.INDEX_RANK);
@@ -167,10 +190,4 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {
}
}
@Override
public void notifyDataSetChanged() {
mLinkedIdentityCache.clear();
super.notifyDataSetChanged();
}
}

View File

@@ -0,0 +1,76 @@
package org.sufficientlysecure.keychain.util;
import android.database.Cursor;
import android.database.CursorWrapper;
public abstract class FilterCursorWrapper extends CursorWrapper {
private int[] mIndex;
private int mCount = 0;
private int mPos = 0;
public abstract boolean isVisible(Cursor cursor);
public FilterCursorWrapper(Cursor cursor) {
super(cursor);
mCount = super.getCount();
mIndex = new int[mCount];
for (int i = 0; i < mCount; i++) {
super.moveToPosition(i);
if (isVisible(cursor)) {
mIndex[mPos++] = i;
}
}
mCount = mPos;
mPos = 0;
super.moveToFirst();
}
@Override
public boolean move(int offset) {
return this.moveToPosition(mPos + offset);
}
@Override
public boolean moveToNext() {
return this.moveToPosition(mPos + 1);
}
@Override
public boolean moveToPrevious() {
return this.moveToPosition(mPos - 1);
}
@Override
public boolean moveToFirst() {
return this.moveToPosition(0);
}
@Override
public boolean moveToLast() {
return this.moveToPosition(mCount - 1);
}
@Override
public boolean moveToPosition(int position) {
if (position >= mCount || position < 0) {
return false;
}
return super.moveToPosition(mIndex[position]);
}
@Override
public int getCount() {
return mCount;
}
public int getHiddenCount() {
return super.getCount() - mCount;
}
@Override
public int getPosition() {
return mPos;
}
}