mirror of
https://github.com/moparisthebest/open-keychain
synced 2025-01-31 07:00:24 -05:00
rework key view into fragments to later add certifications
This commit is contained in:
parent
8f8a787cc9
commit
0c4b809195
@ -30,6 +30,7 @@ import org.spongycastle.openpgp.PGPPublicKey;
|
|||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.spongycastle.openpgp.PGPSignature;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||||
@ -212,6 +213,13 @@ public class ProviderHelper {
|
|||||||
++userIdRank;
|
++userIdRank;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (PGPSignature certification : new IterableIterator<PGPSignature>(masterKey.getSignaturesOfType(PGPSignature.POSITIVE_CERTIFICATION))) {
|
||||||
|
//TODO: how to do this?? we need to verify the signatures again and again when they are displayed...
|
||||||
|
// if (certification.verify
|
||||||
|
// operations.add(buildPublicKeyOperations(context, keyRingRowId, key, rank));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY, operations);
|
context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY, operations);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
@ -33,18 +33,7 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
|
||||||
public class HelpFragmentAbout extends Fragment {
|
public class HelpAboutFragment extends Fragment {
|
||||||
|
|
||||||
/**
|
|
||||||
* Workaround for Android Bug. See
|
|
||||||
* http://stackoverflow.com/questions/8748064/starting-activity-from
|
|
||||||
* -fragment-causes-nullpointerexception
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
setUserVisibleHint(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
@ -20,12 +20,13 @@ package org.sufficientlysecure.keychain.ui;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentPagerAdapter;
|
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
import android.support.v4.view.ViewPager;
|
import android.support.v4.view.ViewPager;
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
@ -37,8 +38,6 @@ public class HelpActivity extends ActionBarActivity {
|
|||||||
|
|
||||||
ViewPager mViewPager;
|
ViewPager mViewPager;
|
||||||
TabsAdapter mTabsAdapter;
|
TabsAdapter mTabsAdapter;
|
||||||
TextView tabCenter;
|
|
||||||
TextView tabText;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@ -63,93 +62,21 @@ public class HelpActivity extends ActionBarActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bundle startBundle = new Bundle();
|
Bundle startBundle = new Bundle();
|
||||||
startBundle.putInt(HelpFragmentHtml.ARG_HTML_FILE, R.raw.help_start);
|
startBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_start);
|
||||||
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_start)),
|
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_start)),
|
||||||
HelpFragmentHtml.class, startBundle, (selectedTab == 0 ? true : false));
|
HelpHtmlFragment.class, startBundle, (selectedTab == 0 ? true : false));
|
||||||
|
|
||||||
Bundle nfcBundle = new Bundle();
|
Bundle nfcBundle = new Bundle();
|
||||||
nfcBundle.putInt(HelpFragmentHtml.ARG_HTML_FILE, R.raw.help_nfc_beam);
|
nfcBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_nfc_beam);
|
||||||
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_nfc_beam)),
|
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_nfc_beam)),
|
||||||
HelpFragmentHtml.class, nfcBundle, (selectedTab == 1 ? true : false));
|
HelpHtmlFragment.class, nfcBundle, (selectedTab == 1 ? true : false));
|
||||||
|
|
||||||
Bundle changelogBundle = new Bundle();
|
Bundle changelogBundle = new Bundle();
|
||||||
changelogBundle.putInt(HelpFragmentHtml.ARG_HTML_FILE, R.raw.help_changelog);
|
changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog);
|
||||||
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_changelog)),
|
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_changelog)),
|
||||||
HelpFragmentHtml.class, changelogBundle, (selectedTab == 2 ? true : false));
|
HelpHtmlFragment.class, changelogBundle, (selectedTab == 2 ? true : false));
|
||||||
|
|
||||||
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_about)),
|
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_about)),
|
||||||
HelpFragmentAbout.class, null, (selectedTab == 3 ? true : false));
|
HelpAboutFragment.class, null, (selectedTab == 3 ? true : false));
|
||||||
}
|
|
||||||
|
|
||||||
public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener,
|
|
||||||
ViewPager.OnPageChangeListener {
|
|
||||||
private final Context mContext;
|
|
||||||
private final ActionBar mActionBar;
|
|
||||||
private final ViewPager mViewPager;
|
|
||||||
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
|
|
||||||
|
|
||||||
static final class TabInfo {
|
|
||||||
private final Class<?> clss;
|
|
||||||
private final Bundle args;
|
|
||||||
|
|
||||||
TabInfo(Class<?> _class, Bundle _args) {
|
|
||||||
clss = _class;
|
|
||||||
args = _args;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TabsAdapter(ActionBarActivity activity, ViewPager pager) {
|
|
||||||
super(activity.getSupportFragmentManager());
|
|
||||||
mContext = activity;
|
|
||||||
mActionBar = activity.getSupportActionBar();
|
|
||||||
mViewPager = pager;
|
|
||||||
mViewPager.setAdapter(this);
|
|
||||||
mViewPager.setOnPageChangeListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args, boolean selected) {
|
|
||||||
TabInfo info = new TabInfo(clss, args);
|
|
||||||
tab.setTag(info);
|
|
||||||
tab.setTabListener(this);
|
|
||||||
mTabs.add(info);
|
|
||||||
mActionBar.addTab(tab, selected);
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return mTabs.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Fragment getItem(int position) {
|
|
||||||
TabInfo info = mTabs.get(position);
|
|
||||||
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPageSelected(int position) {
|
|
||||||
mActionBar.setSelectedNavigationItem(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPageScrollStateChanged(int state) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
|
|
||||||
Object tag = tab.getTag();
|
|
||||||
for (int i = 0; i < mTabs.size(); i++) {
|
|
||||||
if (mTabs.get(i) == tag) {
|
|
||||||
mViewPager.setCurrentItem(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -28,7 +28,7 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ScrollView;
|
import android.widget.ScrollView;
|
||||||
|
|
||||||
public class HelpFragmentHtml extends Fragment {
|
public class HelpHtmlFragment extends Fragment {
|
||||||
private Activity mActivity;
|
private Activity mActivity;
|
||||||
|
|
||||||
private int htmlFile;
|
private int htmlFile;
|
||||||
@ -36,10 +36,10 @@ public class HelpFragmentHtml extends Fragment {
|
|||||||
public static final String ARG_HTML_FILE = "htmlFile";
|
public static final String ARG_HTML_FILE = "htmlFile";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of HelpFragmentHtml, providing "htmlFile" as an argument.
|
* Create a new instance of HelpHtmlFragment, providing "htmlFile" as an argument.
|
||||||
*/
|
*/
|
||||||
static HelpFragmentHtml newInstance(int htmlFile) {
|
static HelpHtmlFragment newInstance(int htmlFile) {
|
||||||
HelpFragmentHtml f = new HelpFragmentHtml();
|
HelpHtmlFragment f = new HelpHtmlFragment();
|
||||||
|
|
||||||
// Supply html raw file input as an argument.
|
// Supply html raw file input as an argument.
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
@ -49,17 +49,6 @@ public class HelpFragmentHtml extends Fragment {
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Workaround for Android Bug. See
|
|
||||||
* http://stackoverflow.com/questions/8748064/starting-activity-from
|
|
||||||
* -fragment-causes-nullpointerexception
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
setUserVisibleHint(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
mActivity = getActivity();
|
mActivity = getActivity();
|
@ -18,8 +18,17 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import android.content.Intent;
|
||||||
import java.util.Date;
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.support.v7.app.ActionBar;
|
||||||
|
import android.support.v7.app.ActionBarActivity;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
@ -27,64 +36,25 @@ import org.sufficientlysecure.keychain.R;
|
|||||||
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
||||||
import org.sufficientlysecure.keychain.helper.ExportHelper;
|
import org.sufficientlysecure.keychain.helper.ExportHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
|
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter;
|
import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter;
|
||||||
import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter;
|
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.ShareQrCodeDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.ShareQrCodeDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
import android.content.Intent;
|
import java.util.ArrayList;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.support.v4.app.LoaderManager;
|
|
||||||
import android.support.v4.content.CursorLoader;
|
|
||||||
import android.support.v4.content.Loader;
|
|
||||||
import android.support.v7.app.ActionBarActivity;
|
|
||||||
import android.text.format.DateFormat;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.beardedhen.androidbootstrap.BootstrapButton;
|
public class ViewKeyActivity extends ActionBarActivity {
|
||||||
|
|
||||||
public class ViewKeyActivity extends ActionBarActivity implements
|
|
||||||
LoaderManager.LoaderCallbacks<Cursor> {
|
|
||||||
|
|
||||||
ExportHelper mExportHelper;
|
ExportHelper mExportHelper;
|
||||||
|
|
||||||
protected Uri mDataUri;
|
protected Uri mDataUri;
|
||||||
|
|
||||||
private TextView mName;
|
public static final String EXTRA_SELECTED_TAB = "selectedTab";
|
||||||
private TextView mEmail;
|
|
||||||
private TextView mComment;
|
|
||||||
private TextView mAlgorithm;
|
|
||||||
private TextView mKeyId;
|
|
||||||
private TextView mExpiry;
|
|
||||||
private TextView mCreation;
|
|
||||||
private TextView mFingerprint;
|
|
||||||
private BootstrapButton mActionEncrypt;
|
|
||||||
private BootstrapButton mActionCertify;
|
|
||||||
|
|
||||||
private ListView mUserIds;
|
ViewPager mViewPager;
|
||||||
private ListView mKeys;
|
TabsAdapter mTabsAdapter;
|
||||||
|
|
||||||
private static final int LOADER_ID_KEYRING = 0;
|
|
||||||
private static final int LOADER_ID_USER_IDS = 1;
|
|
||||||
private static final int LOADER_ID_KEYS = 2;
|
|
||||||
private ViewKeyUserIdsAdapter mUserIdsAdapter;
|
|
||||||
private ViewKeyKeysAdapter mKeysAdapter;
|
|
||||||
|
|
||||||
private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
|
private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
|
||||||
|
|
||||||
@ -95,26 +65,35 @@ public class ViewKeyActivity extends ActionBarActivity implements
|
|||||||
mExportHelper = new ExportHelper(this);
|
mExportHelper = new ExportHelper(this);
|
||||||
|
|
||||||
// let the actionbar look like Android's contact app
|
// let the actionbar look like Android's contact app
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
ActionBar actionBar = getSupportActionBar();
|
||||||
getSupportActionBar().setIcon(android.R.color.transparent);
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
getSupportActionBar().setHomeButtonEnabled(true);
|
actionBar.setIcon(android.R.color.transparent);
|
||||||
|
actionBar.setHomeButtonEnabled(true);
|
||||||
|
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
||||||
|
|
||||||
setContentView(R.layout.view_key_activity);
|
setContentView(R.layout.view_key_activity);
|
||||||
|
|
||||||
mName = (TextView) findViewById(R.id.name);
|
mViewPager = (ViewPager) findViewById(R.id.pager);
|
||||||
mEmail = (TextView) findViewById(R.id.email);
|
|
||||||
mComment = (TextView) findViewById(R.id.comment);
|
|
||||||
mKeyId = (TextView) findViewById(R.id.key_id);
|
|
||||||
mAlgorithm = (TextView) findViewById(R.id.algorithm);
|
|
||||||
mCreation = (TextView) findViewById(R.id.creation);
|
|
||||||
mExpiry = (TextView) findViewById(R.id.expiry);
|
|
||||||
mFingerprint = (TextView) findViewById(R.id.fingerprint);
|
|
||||||
mUserIds = (ListView) findViewById(R.id.user_ids);
|
|
||||||
mKeys = (ListView) findViewById(R.id.keys);
|
|
||||||
mActionEncrypt = (BootstrapButton) findViewById(R.id.action_encrypt);
|
|
||||||
mActionCertify = (BootstrapButton) findViewById(R.id.action_certify);
|
|
||||||
|
|
||||||
loadData(getIntent());
|
mTabsAdapter = new TabsAdapter(this, mViewPager);
|
||||||
|
|
||||||
|
int selectedTab = 0;
|
||||||
|
Intent intent = getIntent();
|
||||||
|
if (intent.getExtras() != null && intent.getExtras().containsKey(EXTRA_SELECTED_TAB)) {
|
||||||
|
selectedTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB);
|
||||||
|
}
|
||||||
|
|
||||||
|
mDataUri = getIntent().getData();
|
||||||
|
|
||||||
|
Bundle mainBundle = new Bundle();
|
||||||
|
mainBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, mDataUri);
|
||||||
|
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_main)),
|
||||||
|
ViewKeyMainFragment.class, mainBundle, (selectedTab == 0 ? true : false));
|
||||||
|
|
||||||
|
Bundle certBundle = new Bundle();
|
||||||
|
certBundle.putParcelable(ViewKeyCertsFragment.ARG_DATA_URI, mDataUri);
|
||||||
|
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_certs)),
|
||||||
|
ViewKeyCertsFragment.class, certBundle, (selectedTab == 1 ? true : false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -168,210 +147,6 @@ public class ViewKeyActivity extends ActionBarActivity implements
|
|||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadData(Intent intent) {
|
|
||||||
if (intent.getData().equals(mDataUri)) {
|
|
||||||
Log.d(Constants.TAG, "Same URI, no need to load the data again!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mDataUri = intent.getData();
|
|
||||||
if (mDataUri == null) {
|
|
||||||
Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
|
|
||||||
|
|
||||||
mActionEncrypt.setOnClickListener(new OnClickListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
encryptToContact(mDataUri);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mActionCertify.setOnClickListener(new OnClickListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
certifyKey(mDataUri);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mUserIdsAdapter = new ViewKeyUserIdsAdapter(this, null, 0);
|
|
||||||
mUserIds.setAdapter(mUserIdsAdapter);
|
|
||||||
// mUserIds.setEmptyView(findViewById(android.R.id.empty));
|
|
||||||
// mUserIds.setClickable(true);
|
|
||||||
// mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
||||||
// @Override
|
|
||||||
// public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
mKeysAdapter = new ViewKeyKeysAdapter(this, null, 0);
|
|
||||||
mKeys.setAdapter(mKeysAdapter);
|
|
||||||
|
|
||||||
// Prepare the loaders. Either re-connect with an existing ones,
|
|
||||||
// or start new ones.
|
|
||||||
getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this);
|
|
||||||
getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
|
|
||||||
getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
static final String[] KEYRING_PROJECTION = new String[]{KeyRings._ID, KeyRings.MASTER_KEY_ID,
|
|
||||||
UserIds.USER_ID};
|
|
||||||
static final int KEYRING_INDEX_ID = 0;
|
|
||||||
static final int KEYRING_INDEX_MASTER_KEY_ID = 1;
|
|
||||||
static final int KEYRING_INDEX_USER_ID = 2;
|
|
||||||
|
|
||||||
static final String[] USER_IDS_PROJECTION = new String[]{UserIds._ID, UserIds.USER_ID,
|
|
||||||
UserIds.RANK,};
|
|
||||||
// not the main user id
|
|
||||||
static final String USER_IDS_SELECTION = UserIds.RANK + " > 0 ";
|
|
||||||
static final String USER_IDS_SORT_ORDER = UserIds.USER_ID + " COLLATE LOCALIZED ASC";
|
|
||||||
|
|
||||||
static final String[] KEYS_PROJECTION = new String[]{Keys._ID, Keys.KEY_ID,
|
|
||||||
Keys.IS_MASTER_KEY, Keys.ALGORITHM, Keys.KEY_SIZE, Keys.CAN_CERTIFY, Keys.CAN_SIGN,
|
|
||||||
Keys.CAN_ENCRYPT, Keys.CREATION, Keys.EXPIRY, Keys.FINGERPRINT};
|
|
||||||
static final String KEYS_SORT_ORDER = Keys.RANK + " ASC";
|
|
||||||
static final int KEYS_INDEX_ID = 0;
|
|
||||||
static final int KEYS_INDEX_KEY_ID = 1;
|
|
||||||
static final int KEYS_INDEX_IS_MASTER_KEY = 2;
|
|
||||||
static final int KEYS_INDEX_ALGORITHM = 3;
|
|
||||||
static final int KEYS_INDEX_KEY_SIZE = 4;
|
|
||||||
static final int KEYS_INDEX_CAN_CERTIFY = 5;
|
|
||||||
static final int KEYS_INDEX_CAN_SIGN = 6;
|
|
||||||
static final int KEYS_INDEX_CAN_ENCRYPT = 7;
|
|
||||||
static final int KEYS_INDEX_CREATION = 8;
|
|
||||||
static final int KEYS_INDEX_EXPIRY = 9;
|
|
||||||
static final int KEYS_INDEX_FINGERPRINT = 10;
|
|
||||||
|
|
||||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
|
||||||
switch (id) {
|
|
||||||
case LOADER_ID_KEYRING: {
|
|
||||||
Uri baseUri = mDataUri;
|
|
||||||
|
|
||||||
// Now create and return a CursorLoader that will take care of
|
|
||||||
// creating a Cursor for the data being displayed.
|
|
||||||
return new CursorLoader(this, baseUri, KEYRING_PROJECTION, null, null, null);
|
|
||||||
}
|
|
||||||
case LOADER_ID_USER_IDS: {
|
|
||||||
Uri baseUri = UserIds.buildUserIdsUri(mDataUri);
|
|
||||||
|
|
||||||
// Now create and return a CursorLoader that will take care of
|
|
||||||
// creating a Cursor for the data being displayed.
|
|
||||||
return new CursorLoader(this, baseUri, USER_IDS_PROJECTION, USER_IDS_SELECTION, null,
|
|
||||||
USER_IDS_SORT_ORDER);
|
|
||||||
}
|
|
||||||
case LOADER_ID_KEYS: {
|
|
||||||
Uri baseUri = Keys.buildKeysUri(mDataUri);
|
|
||||||
|
|
||||||
// Now create and return a CursorLoader that will take care of
|
|
||||||
// creating a Cursor for the data being displayed.
|
|
||||||
return new CursorLoader(this, baseUri, KEYS_PROJECTION, null, null, KEYS_SORT_ORDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
|
|
||||||
// Swap the new cursor in. (The framework will take care of closing the
|
|
||||||
// old cursor once we return.)
|
|
||||||
switch (loader.getId()) {
|
|
||||||
case LOADER_ID_KEYRING:
|
|
||||||
if (data.moveToFirst()) {
|
|
||||||
// get name, email, and comment from USER_ID
|
|
||||||
String[] mainUserId = PgpKeyHelper.splitUserId(data
|
|
||||||
.getString(KEYRING_INDEX_USER_ID));
|
|
||||||
if (mainUserId[0] != null) {
|
|
||||||
setTitle(mainUserId[0]);
|
|
||||||
mName.setText(mainUserId[0]);
|
|
||||||
} else {
|
|
||||||
setTitle(R.string.user_id_no_name);
|
|
||||||
mName.setText(R.string.user_id_no_name);
|
|
||||||
}
|
|
||||||
mEmail.setText(mainUserId[1]);
|
|
||||||
mComment.setText(mainUserId[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case LOADER_ID_USER_IDS:
|
|
||||||
mUserIdsAdapter.swapCursor(data);
|
|
||||||
break;
|
|
||||||
case LOADER_ID_KEYS:
|
|
||||||
// the first key here is our master key
|
|
||||||
if (data.moveToFirst()) {
|
|
||||||
// get key id from MASTER_KEY_ID
|
|
||||||
long keyId = data.getLong(KEYS_INDEX_KEY_ID);
|
|
||||||
|
|
||||||
String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
|
|
||||||
mKeyId.setText(keyIdStr);
|
|
||||||
|
|
||||||
// get creation date from CREATION
|
|
||||||
if (data.isNull(KEYS_INDEX_CREATION)) {
|
|
||||||
mCreation.setText(R.string.none);
|
|
||||||
} else {
|
|
||||||
Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000);
|
|
||||||
|
|
||||||
mCreation.setText(DateFormat.getDateFormat(getApplicationContext()).format(
|
|
||||||
creationDate));
|
|
||||||
}
|
|
||||||
|
|
||||||
// get expiry date from EXPIRY
|
|
||||||
if (data.isNull(KEYS_INDEX_EXPIRY)) {
|
|
||||||
mExpiry.setText(R.string.none);
|
|
||||||
} else {
|
|
||||||
Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000);
|
|
||||||
|
|
||||||
mExpiry.setText(DateFormat.getDateFormat(getApplicationContext()).format(
|
|
||||||
expiryDate));
|
|
||||||
}
|
|
||||||
|
|
||||||
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
|
|
||||||
data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE));
|
|
||||||
mAlgorithm.setText(algorithmStr);
|
|
||||||
|
|
||||||
byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
|
|
||||||
if (fingerprintBlob == null) {
|
|
||||||
// FALLBACK for old database entries
|
|
||||||
fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri);
|
|
||||||
}
|
|
||||||
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
|
|
||||||
fingerprint = fingerprint.replace(" ", "\n");
|
|
||||||
|
|
||||||
mFingerprint.setText(fingerprint);
|
|
||||||
}
|
|
||||||
|
|
||||||
mKeysAdapter.swapCursor(data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
|
|
||||||
* We need to make sure we are no longer using it.
|
|
||||||
*/
|
|
||||||
public void onLoaderReset(Loader<Cursor> loader) {
|
|
||||||
switch (loader.getId()) {
|
|
||||||
case LOADER_ID_KEYRING:
|
|
||||||
// No resources need to be freed for this ID
|
|
||||||
break;
|
|
||||||
case LOADER_ID_USER_IDS:
|
|
||||||
mUserIdsAdapter.swapCursor(null);
|
|
||||||
break;
|
|
||||||
case LOADER_ID_KEYS:
|
|
||||||
mKeysAdapter.swapCursor(null);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void uploadToKeyserver(Uri dataUri) {
|
private void uploadToKeyserver(Uri dataUri) {
|
||||||
Intent uploadIntent = new Intent(this, UploadKeyActivity.class);
|
Intent uploadIntent = new Intent(this, UploadKeyActivity.class);
|
||||||
uploadIntent.setData(dataUri);
|
uploadIntent.setData(dataUri);
|
||||||
@ -394,25 +169,8 @@ public class ViewKeyActivity extends ActionBarActivity implements
|
|||||||
startActivityForResult(queryIntent, RESULT_CODE_LOOKUP_KEY);
|
startActivityForResult(queryIntent, RESULT_CODE_LOOKUP_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encryptToContact(Uri dataUri) {
|
|
||||||
long keyId = ProviderHelper.getMasterKeyId(ViewKeyActivity.this, dataUri);
|
|
||||||
|
|
||||||
long[] encryptionKeyIds = new long[]{keyId};
|
|
||||||
Intent intent = new Intent(ViewKeyActivity.this, EncryptActivity.class);
|
|
||||||
intent.setAction(EncryptActivity.ACTION_ENCRYPT);
|
|
||||||
intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
|
|
||||||
// used instead of startActivity set actionbar based on callingPackage
|
|
||||||
startActivityForResult(intent, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void certifyKey(Uri dataUri) {
|
|
||||||
Intent signIntent = new Intent(this, CertifyKeyActivity.class);
|
|
||||||
signIntent.setData(dataUri);
|
|
||||||
startActivity(signIntent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void shareKey(Uri dataUri, boolean fingerprintOnly) {
|
private void shareKey(Uri dataUri, boolean fingerprintOnly) {
|
||||||
String content = null;
|
String content;
|
||||||
if (fingerprintOnly) {
|
if (fingerprintOnly) {
|
||||||
byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri);
|
byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri);
|
||||||
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, false);
|
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, false);
|
||||||
|
@ -23,7 +23,6 @@ import org.sufficientlysecure.keychain.R;
|
|||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.nfc.NdefMessage;
|
import android.nfc.NdefMessage;
|
||||||
import android.nfc.NdefRecord;
|
import android.nfc.NdefRecord;
|
||||||
@ -35,12 +34,11 @@ import android.os.Build;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.support.v4.app.LoaderManager;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
||||||
public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMessageCallback,
|
public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMessageCallback,
|
||||||
OnNdefPushCompleteCallback, LoaderManager.LoaderCallbacks<Cursor> {
|
OnNdefPushCompleteCallback {
|
||||||
|
|
||||||
// NFC
|
// NFC
|
||||||
private NfcAdapter mNfcAdapter;
|
private NfcAdapter mNfcAdapter;
|
||||||
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.beardedhen.androidbootstrap.BootstrapButton;
|
||||||
|
|
||||||
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
|
|
||||||
|
public class ViewKeyCertsFragment extends Fragment {
|
||||||
|
|
||||||
|
public static final String ARG_DATA_URI = "uri";
|
||||||
|
|
||||||
|
private BootstrapButton mActionCertify;
|
||||||
|
|
||||||
|
private Uri mDataUri;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
View view = inflater.inflate(R.layout.view_key_certs_fragment, container, false);
|
||||||
|
|
||||||
|
mActionCertify = (BootstrapButton) view.findViewById(R.id.action_certify);
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
|
||||||
|
Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
|
||||||
|
if (dataUri == null) {
|
||||||
|
Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
|
||||||
|
getActivity().finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadData(dataUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadData(Uri dataUri) {
|
||||||
|
if (dataUri.equals(mDataUri)) {
|
||||||
|
Log.d(Constants.TAG, "Same URI, no need to load the data again!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDataUri = dataUri;
|
||||||
|
|
||||||
|
Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
|
||||||
|
|
||||||
|
mActionCertify.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
certifyKey(mDataUri);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void certifyKey(Uri dataUri) {
|
||||||
|
Intent signIntent = new Intent(getActivity(), CertifyKeyActivity.class);
|
||||||
|
signIntent.setData(dataUri);
|
||||||
|
startActivity(signIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,313 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.app.LoaderManager;
|
||||||
|
import android.support.v4.content.CursorLoader;
|
||||||
|
import android.support.v4.content.Loader;
|
||||||
|
import android.text.format.DateFormat;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.beardedhen.androidbootstrap.BootstrapButton;
|
||||||
|
|
||||||
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
|
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||||
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
|
import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter;
|
||||||
|
import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
|
public class ViewKeyMainFragment extends Fragment implements
|
||||||
|
LoaderManager.LoaderCallbacks<Cursor>{
|
||||||
|
|
||||||
|
public static final String ARG_DATA_URI = "uri";
|
||||||
|
|
||||||
|
private TextView mName;
|
||||||
|
private TextView mEmail;
|
||||||
|
private TextView mComment;
|
||||||
|
private TextView mAlgorithm;
|
||||||
|
private TextView mKeyId;
|
||||||
|
private TextView mExpiry;
|
||||||
|
private TextView mCreation;
|
||||||
|
private TextView mFingerprint;
|
||||||
|
private BootstrapButton mActionEncrypt;
|
||||||
|
|
||||||
|
private ListView mUserIds;
|
||||||
|
private ListView mKeys;
|
||||||
|
|
||||||
|
private static final int LOADER_ID_KEYRING = 0;
|
||||||
|
private static final int LOADER_ID_USER_IDS = 1;
|
||||||
|
private static final int LOADER_ID_KEYS = 2;
|
||||||
|
|
||||||
|
private ViewKeyUserIdsAdapter mUserIdsAdapter;
|
||||||
|
private ViewKeyKeysAdapter mKeysAdapter;
|
||||||
|
|
||||||
|
private Uri mDataUri;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
View view = inflater.inflate(R.layout.view_key_main_fragment, container, false);
|
||||||
|
|
||||||
|
mName = (TextView) view.findViewById(R.id.name);
|
||||||
|
mEmail = (TextView) view.findViewById(R.id.email);
|
||||||
|
mComment = (TextView) view.findViewById(R.id.comment);
|
||||||
|
mKeyId = (TextView) view.findViewById(R.id.key_id);
|
||||||
|
mAlgorithm = (TextView) view.findViewById(R.id.algorithm);
|
||||||
|
mCreation = (TextView) view.findViewById(R.id.creation);
|
||||||
|
mExpiry = (TextView) view.findViewById(R.id.expiry);
|
||||||
|
mFingerprint = (TextView) view.findViewById(R.id.fingerprint);
|
||||||
|
mUserIds = (ListView) view.findViewById(R.id.user_ids);
|
||||||
|
mKeys = (ListView) view.findViewById(R.id.keys);
|
||||||
|
mActionEncrypt = (BootstrapButton) view.findViewById(R.id.action_encrypt);
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
|
||||||
|
Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
|
||||||
|
if (dataUri == null) {
|
||||||
|
Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
|
||||||
|
getActivity().finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadData(dataUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadData(Uri dataUri) {
|
||||||
|
if (dataUri.equals(mDataUri)) {
|
||||||
|
Log.d(Constants.TAG, "Same URI, no need to load the data again!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDataUri = dataUri;
|
||||||
|
|
||||||
|
Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
|
||||||
|
|
||||||
|
mActionEncrypt.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
encryptToContact(mDataUri);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mUserIdsAdapter = new ViewKeyUserIdsAdapter(getActivity(), null, 0);
|
||||||
|
mUserIds.setAdapter(mUserIdsAdapter);
|
||||||
|
|
||||||
|
mKeysAdapter = new ViewKeyKeysAdapter(getActivity(), null, 0);
|
||||||
|
mKeys.setAdapter(mKeysAdapter);
|
||||||
|
|
||||||
|
// Prepare the loaders. Either re-connect with an existing ones,
|
||||||
|
// or start new ones.
|
||||||
|
getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this);
|
||||||
|
getActivity().getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
|
||||||
|
getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static final String[] KEYRING_PROJECTION = new String[]{KeychainContract.KeyRings._ID, KeychainContract.KeyRings.MASTER_KEY_ID,
|
||||||
|
KeychainContract.UserIds.USER_ID};
|
||||||
|
static final int KEYRING_INDEX_ID = 0;
|
||||||
|
static final int KEYRING_INDEX_MASTER_KEY_ID = 1;
|
||||||
|
static final int KEYRING_INDEX_USER_ID = 2;
|
||||||
|
|
||||||
|
static final String[] USER_IDS_PROJECTION = new String[]{KeychainContract.UserIds._ID, KeychainContract.UserIds.USER_ID,
|
||||||
|
KeychainContract.UserIds.RANK,};
|
||||||
|
// not the main user id
|
||||||
|
static final String USER_IDS_SELECTION = KeychainContract.UserIds.RANK + " > 0 ";
|
||||||
|
static final String USER_IDS_SORT_ORDER = KeychainContract.UserIds.USER_ID + " COLLATE LOCALIZED ASC";
|
||||||
|
|
||||||
|
static final String[] KEYS_PROJECTION = new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID,
|
||||||
|
KeychainContract.Keys.IS_MASTER_KEY, KeychainContract.Keys.ALGORITHM, KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY, KeychainContract.Keys.CAN_SIGN,
|
||||||
|
KeychainContract.Keys.CAN_ENCRYPT, KeychainContract.Keys.CREATION, KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT};
|
||||||
|
static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC";
|
||||||
|
static final int KEYS_INDEX_ID = 0;
|
||||||
|
static final int KEYS_INDEX_KEY_ID = 1;
|
||||||
|
static final int KEYS_INDEX_IS_MASTER_KEY = 2;
|
||||||
|
static final int KEYS_INDEX_ALGORITHM = 3;
|
||||||
|
static final int KEYS_INDEX_KEY_SIZE = 4;
|
||||||
|
static final int KEYS_INDEX_CAN_CERTIFY = 5;
|
||||||
|
static final int KEYS_INDEX_CAN_SIGN = 6;
|
||||||
|
static final int KEYS_INDEX_CAN_ENCRYPT = 7;
|
||||||
|
static final int KEYS_INDEX_CREATION = 8;
|
||||||
|
static final int KEYS_INDEX_EXPIRY = 9;
|
||||||
|
static final int KEYS_INDEX_FINGERPRINT = 10;
|
||||||
|
|
||||||
|
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||||
|
switch (id) {
|
||||||
|
case LOADER_ID_KEYRING: {
|
||||||
|
Uri baseUri = mDataUri;
|
||||||
|
|
||||||
|
// Now create and return a CursorLoader that will take care of
|
||||||
|
// creating a Cursor for the data being displayed.
|
||||||
|
return new CursorLoader(getActivity(), baseUri, KEYRING_PROJECTION, null, null, null);
|
||||||
|
}
|
||||||
|
case LOADER_ID_USER_IDS: {
|
||||||
|
Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri);
|
||||||
|
|
||||||
|
// Now create and return a CursorLoader that will take care of
|
||||||
|
// creating a Cursor for the data being displayed.
|
||||||
|
return new CursorLoader(getActivity(), baseUri, USER_IDS_PROJECTION, USER_IDS_SELECTION, null,
|
||||||
|
USER_IDS_SORT_ORDER);
|
||||||
|
}
|
||||||
|
case LOADER_ID_KEYS: {
|
||||||
|
Uri baseUri = KeychainContract.Keys.buildKeysUri(mDataUri);
|
||||||
|
|
||||||
|
// Now create and return a CursorLoader that will take care of
|
||||||
|
// creating a Cursor for the data being displayed.
|
||||||
|
return new CursorLoader(getActivity(), baseUri, KEYS_PROJECTION, null, null, KEYS_SORT_ORDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
|
||||||
|
// Swap the new cursor in. (The framework will take care of closing the
|
||||||
|
// old cursor once we return.)
|
||||||
|
switch (loader.getId()) {
|
||||||
|
case LOADER_ID_KEYRING:
|
||||||
|
if (data.moveToFirst()) {
|
||||||
|
// get name, email, and comment from USER_ID
|
||||||
|
String[] mainUserId = PgpKeyHelper.splitUserId(data
|
||||||
|
.getString(KEYRING_INDEX_USER_ID));
|
||||||
|
if (mainUserId[0] != null) {
|
||||||
|
getActivity().setTitle(mainUserId[0]);
|
||||||
|
mName.setText(mainUserId[0]);
|
||||||
|
} else {
|
||||||
|
getActivity().setTitle(R.string.user_id_no_name);
|
||||||
|
mName.setText(R.string.user_id_no_name);
|
||||||
|
}
|
||||||
|
mEmail.setText(mainUserId[1]);
|
||||||
|
mComment.setText(mainUserId[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case LOADER_ID_USER_IDS:
|
||||||
|
mUserIdsAdapter.swapCursor(data);
|
||||||
|
break;
|
||||||
|
case LOADER_ID_KEYS:
|
||||||
|
// the first key here is our master key
|
||||||
|
if (data.moveToFirst()) {
|
||||||
|
// get key id from MASTER_KEY_ID
|
||||||
|
long keyId = data.getLong(KEYS_INDEX_KEY_ID);
|
||||||
|
|
||||||
|
String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
|
||||||
|
mKeyId.setText(keyIdStr);
|
||||||
|
|
||||||
|
// get creation date from CREATION
|
||||||
|
if (data.isNull(KEYS_INDEX_CREATION)) {
|
||||||
|
mCreation.setText(R.string.none);
|
||||||
|
} else {
|
||||||
|
Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000);
|
||||||
|
|
||||||
|
mCreation.setText(DateFormat.getDateFormat(getActivity().getApplicationContext()).format(
|
||||||
|
creationDate));
|
||||||
|
}
|
||||||
|
|
||||||
|
// get expiry date from EXPIRY
|
||||||
|
if (data.isNull(KEYS_INDEX_EXPIRY)) {
|
||||||
|
mExpiry.setText(R.string.none);
|
||||||
|
} else {
|
||||||
|
Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000);
|
||||||
|
|
||||||
|
mExpiry.setText(DateFormat.getDateFormat(getActivity().getApplicationContext()).format(
|
||||||
|
expiryDate));
|
||||||
|
}
|
||||||
|
|
||||||
|
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
|
||||||
|
data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE));
|
||||||
|
mAlgorithm.setText(algorithmStr);
|
||||||
|
|
||||||
|
byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
|
||||||
|
if (fingerprintBlob == null) {
|
||||||
|
// FALLBACK for old database entries
|
||||||
|
fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), mDataUri);
|
||||||
|
}
|
||||||
|
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
|
||||||
|
fingerprint = fingerprint.replace(" ", "\n");
|
||||||
|
|
||||||
|
mFingerprint.setText(fingerprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
mKeysAdapter.swapCursor(data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
|
||||||
|
* We need to make sure we are no longer using it.
|
||||||
|
*/
|
||||||
|
public void onLoaderReset(Loader<Cursor> loader) {
|
||||||
|
switch (loader.getId()) {
|
||||||
|
case LOADER_ID_KEYRING:
|
||||||
|
// No resources need to be freed for this ID
|
||||||
|
break;
|
||||||
|
case LOADER_ID_USER_IDS:
|
||||||
|
mUserIdsAdapter.swapCursor(null);
|
||||||
|
break;
|
||||||
|
case LOADER_ID_KEYS:
|
||||||
|
mKeysAdapter.swapCursor(null);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void encryptToContact(Uri dataUri) {
|
||||||
|
long keyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
|
||||||
|
|
||||||
|
long[] encryptionKeyIds = new long[]{keyId};
|
||||||
|
Intent intent = new Intent(getActivity(), EncryptActivity.class);
|
||||||
|
intent.setAction(EncryptActivity.ACTION_ENCRYPT);
|
||||||
|
intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
|
||||||
|
// used instead of startActivity set actionbar based on callingPackage
|
||||||
|
startActivityForResult(intent, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void certifyKey(Uri dataUri) {
|
||||||
|
Intent signIntent = new Intent(getActivity(), CertifyKeyActivity.class);
|
||||||
|
signIntent.setData(dataUri);
|
||||||
|
startActivity(signIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
package org.sufficientlysecure.keychain.ui.adapter;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||||
|
import android.support.v4.app.FragmentTransaction;
|
||||||
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.support.v7.app.ActionBar;
|
||||||
|
import android.support.v7.app.ActionBarActivity;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar.TabListener,
|
||||||
|
ViewPager.OnPageChangeListener {
|
||||||
|
private final Context mContext;
|
||||||
|
private final ActionBar mActionBar;
|
||||||
|
private final ViewPager mViewPager;
|
||||||
|
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
|
||||||
|
|
||||||
|
static final class TabInfo {
|
||||||
|
private final Class<?> clss;
|
||||||
|
private final Bundle args;
|
||||||
|
|
||||||
|
TabInfo(Class<?> _class, Bundle _args) {
|
||||||
|
clss = _class;
|
||||||
|
args = _args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TabsAdapter(ActionBarActivity activity, ViewPager pager) {
|
||||||
|
super(activity.getSupportFragmentManager());
|
||||||
|
mContext = activity;
|
||||||
|
mActionBar = activity.getSupportActionBar();
|
||||||
|
mViewPager = pager;
|
||||||
|
mViewPager.setAdapter(this);
|
||||||
|
mViewPager.setOnPageChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args, boolean selected) {
|
||||||
|
TabInfo info = new TabInfo(clss, args);
|
||||||
|
tab.setTag(info);
|
||||||
|
tab.setTabListener(this);
|
||||||
|
mTabs.add(info);
|
||||||
|
mActionBar.addTab(tab, selected);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return mTabs.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fragment getItem(int position) {
|
||||||
|
TabInfo info = mTabs.get(position);
|
||||||
|
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
mActionBar.setSelectedNavigationItem(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||||
|
Object tag = tab.getTag();
|
||||||
|
for (int i = 0; i < mTabs.size(); i++) {
|
||||||
|
if (mTabs.get(i) == tag) {
|
||||||
|
mViewPager.setCurrentItem(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||||
|
}
|
||||||
|
}
|
@ -1,229 +1,12 @@
|
|||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
<LinearLayout
|
<android.support.v4.view.ViewPager
|
||||||
|
android:id="@+id/pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent" />
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingRight="16dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="@style/SectionHeader"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:layout_marginTop="14dp"
|
|
||||||
android:text="@string/section_master_user_id" />
|
|
||||||
|
|
||||||
<TableLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:stretchColumns="1">
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="top"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_name" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/name"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingRight="5dip"
|
|
||||||
android:text="" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="top"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_email" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/email"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingRight="5dip"
|
|
||||||
android:text="" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="top"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_comment" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/comment"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingRight="5dip"
|
|
||||||
android:text="" />
|
|
||||||
</TableRow>
|
|
||||||
</TableLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="@style/SectionHeader"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:layout_marginTop="14dp"
|
|
||||||
android:text="@string/section_master_key" />
|
|
||||||
|
|
||||||
<TableLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:stretchColumns="1">
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_key_id" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/key_id"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingRight="5dip"
|
|
||||||
android:text=""
|
|
||||||
android:typeface="monospace" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label_algorithm"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_algorithm" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/algorithm"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingRight="5dip"
|
|
||||||
android:text="" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_creation" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/creation"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_expiry" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/expiry"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_fingerprint" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fingerprint"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:typeface="monospace" />
|
|
||||||
</TableRow>
|
|
||||||
</TableLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="@style/SectionHeader"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:layout_marginTop="14dp"
|
|
||||||
android:text="@string/section_user_ids" />
|
|
||||||
|
|
||||||
<org.sufficientlysecure.keychain.ui.widget.FixedListView
|
|
||||||
android:id="@+id/user_ids"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="@style/SectionHeader"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:layout_marginTop="14dp"
|
|
||||||
android:text="@string/section_keys" />
|
|
||||||
|
|
||||||
<org.sufficientlysecure.keychain.ui.widget.FixedListView
|
|
||||||
android:id="@+id/keys"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="@style/SectionHeader"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:layout_marginTop="14dp"
|
|
||||||
android:text="@string/section_actions" />
|
|
||||||
|
|
||||||
<com.beardedhen.androidbootstrap.BootstrapButton
|
|
||||||
android:id="@+id/action_encrypt"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="60dp"
|
|
||||||
android:padding="4dp"
|
|
||||||
android:text="@string/key_view_action_encrypt"
|
|
||||||
bootstrapbutton:bb_icon_left="fa-lock"
|
|
||||||
bootstrapbutton:bb_type="info" />
|
|
||||||
|
|
||||||
<com.beardedhen.androidbootstrap.BootstrapButton
|
|
||||||
android:id="@+id/action_certify"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="60dp"
|
|
||||||
android:padding="4dp"
|
|
||||||
android:text="@string/key_view_action_certify"
|
|
||||||
bootstrapbutton:bb_icon_left="fa-pencil"
|
|
||||||
bootstrapbutton:bb_type="info" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</ScrollView>
|
|
@ -0,0 +1,31 @@
|
|||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/SectionHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:layout_marginTop="14dp"
|
||||||
|
android:text="@string/section_actions" />
|
||||||
|
|
||||||
|
<com.beardedhen.androidbootstrap.BootstrapButton
|
||||||
|
android:id="@+id/action_certify"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:text="@string/key_view_action_certify"
|
||||||
|
bootstrapbutton:bb_icon_left="fa-pencil"
|
||||||
|
bootstrapbutton:bb_type="info" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
@ -1,8 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?android:attr/listPreferredItemHeight"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginRight="?android:attr/scrollbarSize"
|
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingLeft="8dip"
|
android:paddingLeft="8dip"
|
||||||
android:paddingRight="3dip"
|
android:paddingRight="3dip"
|
||||||
|
222
OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml
Normal file
222
OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/SectionHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:layout_marginTop="14dp"
|
||||||
|
android:text="@string/section_master_user_id" />
|
||||||
|
|
||||||
|
<TableLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:stretchColumns="1">
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="top"
|
||||||
|
android:paddingRight="10dip"
|
||||||
|
android:text="@string/label_name" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/name"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dip"
|
||||||
|
android:text="" />
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="top"
|
||||||
|
android:paddingRight="10dip"
|
||||||
|
android:text="@string/label_email" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/email"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dip"
|
||||||
|
android:text="" />
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="top"
|
||||||
|
android:paddingRight="10dip"
|
||||||
|
android:text="@string/label_comment" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/comment"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dip"
|
||||||
|
android:text="" />
|
||||||
|
</TableRow>
|
||||||
|
</TableLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/SectionHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:layout_marginTop="14dp"
|
||||||
|
android:text="@string/section_actions" />
|
||||||
|
|
||||||
|
<com.beardedhen.androidbootstrap.BootstrapButton
|
||||||
|
android:id="@+id/action_encrypt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:text="@string/key_view_action_encrypt"
|
||||||
|
bootstrapbutton:bb_icon_left="fa-lock"
|
||||||
|
bootstrapbutton:bb_type="info" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/SectionHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:layout_marginTop="14dp"
|
||||||
|
android:text="@string/section_master_key" />
|
||||||
|
|
||||||
|
<TableLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:stretchColumns="1">
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingRight="10dip"
|
||||||
|
android:text="@string/label_key_id" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_id"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dip"
|
||||||
|
android:text=""
|
||||||
|
android:typeface="monospace" />
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/label_algorithm"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingRight="10dip"
|
||||||
|
android:text="@string/label_algorithm" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/algorithm"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dip"
|
||||||
|
android:text="" />
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingRight="10dip"
|
||||||
|
android:text="@string/label_creation" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/creation"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingRight="10dip"
|
||||||
|
android:text="@string/label_expiry" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/expiry"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingRight="10dip"
|
||||||
|
android:text="@string/label_fingerprint" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/fingerprint"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:typeface="monospace" />
|
||||||
|
</TableRow>
|
||||||
|
</TableLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/SectionHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:layout_marginTop="14dp"
|
||||||
|
android:text="@string/section_user_ids" />
|
||||||
|
|
||||||
|
<org.sufficientlysecure.keychain.ui.widget.FixedListView
|
||||||
|
android:id="@+id/user_ids"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/SectionHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:layout_marginTop="14dp"
|
||||||
|
android:text="@string/section_keys" />
|
||||||
|
|
||||||
|
<org.sufficientlysecure.keychain.ui.widget.FixedListView
|
||||||
|
android:id="@+id/keys"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="14dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
@ -1,16 +1,15 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?android:attr/listPreferredItemHeight"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginRight="?android:attr/scrollbarSize"
|
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
|
android:paddingRight="3dip"
|
||||||
android:singleLine="true">
|
android:singleLine="true">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/userId"
|
android:id="@+id/userId"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingRight="3dip"
|
|
||||||
android:text="User ID"
|
android:text="User ID"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
@ -414,6 +414,8 @@
|
|||||||
<!-- Key view -->
|
<!-- Key view -->
|
||||||
<string name="key_view_action_encrypt">Encrypt to this contact</string>
|
<string name="key_view_action_encrypt">Encrypt to this contact</string>
|
||||||
<string name="key_view_action_certify">Certify this contact\'s key</string>
|
<string name="key_view_action_certify">Certify this contact\'s key</string>
|
||||||
|
<string name="key_view_tab_main">Info</string>
|
||||||
|
<string name="key_view_tab_certs">Certifications</string>
|
||||||
|
|
||||||
<!-- Navigation Drawer -->
|
<!-- Navigation Drawer -->
|
||||||
<string name="nav_contacts">Contacts</string>
|
<string name="nav_contacts">Contacts</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user