Merge branch 'master' of github.com:open-keychain/open-keychain

This commit is contained in:
Dominik Schürmann
2014-05-07 09:05:38 +02:00
27 changed files with 180 additions and 223 deletions

View File

@@ -18,6 +18,9 @@
package org.sufficientlysecure.keychain;
import android.app.Application;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import org.spongycastle.jce.provider.BouncyCastleProvider;
@@ -70,5 +73,22 @@ public class KeychainApplication extends Application {
// that the directory doesn't exist at this point
}
}
brandGlowEffect(getApplicationContext(),
getApplicationContext().getResources().getColor(R.color.emphasis));
}
static void brandGlowEffect(Context context, int brandColor) {
// terrible hack to brand the edge overscroll glow effect
// https://gist.github.com/menny/7878762#file-brandgloweffect_full-java
//glow
int glowDrawableId = context.getResources().getIdentifier("overscroll_glow", "drawable", "android");
Drawable androidGlow = context.getResources().getDrawable(glowDrawableId);
androidGlow.setColorFilter(brandColor, PorterDuff.Mode.SRC_IN);
//edge
int edgeDrawableId = context.getResources().getIdentifier("overscroll_edge", "drawable", "android");
Drawable androidEdge = context.getResources().getDrawable(edgeDrawableId);
androidEdge.setColorFilter(brandColor, PorterDuff.Mode.SRC_IN);
}
}

View File

@@ -24,7 +24,9 @@ import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter;
import org.sufficientlysecure.keychain.util.SlidingTabLayout;
public class HelpActivity extends ActionBarActivity {
public static final String EXTRA_SELECTED_TAB = "selected_tab";
@@ -37,25 +39,27 @@ public class HelpActivity extends ActionBarActivity {
public static final int TAB_ABOUT = 5;
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
private PagerTabStripAdapter mTabsAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.help_activity);
mViewPager = (ViewPager) findViewById(R.id.pager);
final ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mTabsAdapter = new TabsAdapter(this, mViewPager);
setContentView(R.layout.help_activity);
int selectedTab = 0;
mViewPager = (ViewPager) findViewById(R.id.pager);
SlidingTabLayout slidingTabLayout =
(SlidingTabLayout) findViewById(R.id.sliding_tab_layout);
mTabsAdapter = new PagerTabStripAdapter(this);
mViewPager.setAdapter(mTabsAdapter);
int selectedTab = TAB_START;
Intent intent = getIntent();
if (intent.getExtras() != null && intent.getExtras().containsKey(EXTRA_SELECTED_TAB)) {
selectedTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB);
@@ -63,30 +67,36 @@ public class HelpActivity extends ActionBarActivity {
Bundle startBundle = new Bundle();
startBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_start);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_start)),
HelpHtmlFragment.class, startBundle, (selectedTab == TAB_START));
mTabsAdapter.addTab(HelpHtmlFragment.class, startBundle,
getString(R.string.help_tab_start));
Bundle faqBundle = new Bundle();
faqBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_faq);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_faq)),
HelpHtmlFragment.class, faqBundle, (selectedTab == TAB_FAQ));
mTabsAdapter.addTab(HelpHtmlFragment.class, faqBundle,
getString(R.string.help_tab_faq));
Bundle wotBundle = new Bundle();
wotBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_wot);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_wot)),
HelpHtmlFragment.class, wotBundle, (selectedTab == TAB_WOT));
mTabsAdapter.addTab(HelpHtmlFragment.class, wotBundle,
getString(R.string.help_tab_wot));
Bundle nfcBundle = new Bundle();
nfcBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_nfc_beam);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_nfc_beam)),
HelpHtmlFragment.class, nfcBundle, (selectedTab == TAB_NFC));
mTabsAdapter.addTab(HelpHtmlFragment.class, nfcBundle,
getString(R.string.help_tab_nfc_beam));
Bundle changelogBundle = new Bundle();
changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_changelog)),
HelpHtmlFragment.class, changelogBundle, (selectedTab == TAB_CHANGELOG));
mTabsAdapter.addTab(HelpHtmlFragment.class, changelogBundle,
getString(R.string.help_tab_changelog));
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_about)),
HelpAboutFragment.class, null, (selectedTab == TAB_ABOUT));
mTabsAdapter.addTab(HelpAboutFragment.class, null,
getString(R.string.help_tab_about));
// NOTE: must be after adding the tabs!
slidingTabLayout.setViewPager(mViewPager);
// switch to tab selected by extra
mViewPager.setCurrentItem(selectedTab);
}
}

View File

@@ -381,6 +381,9 @@ public class KeyListFragment extends Fragment
// Execute this when searching
mSearchView.setOnQueryTextListener(this);
View searchPlate = mSearchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
searchPlate.setBackgroundResource(R.drawable.keychaintheme_searchview_holo_light);
// Erase search result without focus
MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
@Override

View File

@@ -40,6 +40,7 @@ import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import com.devspark.appmsg.AppMsg;
@@ -55,6 +56,7 @@ import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.SlidingTabLayout;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
public class ViewKeyActivity extends ActionBarActivity implements
@@ -75,6 +77,9 @@ public class ViewKeyActivity extends ActionBarActivity implements
private ViewPager mViewPager;
private SlidingTabLayout mSlidingTabLayout;
private PagerTabStripAdapter mTabsAdapter;
private View mStatusDivider;
private View mStatusRevoked;
private View mStatusExpired;
public static final int REQUEST_CODE_LOOKUP_KEY = 0x00007006;
@@ -104,6 +109,10 @@ public class ViewKeyActivity extends ActionBarActivity implements
setContentView(R.layout.view_key_activity);
mStatusDivider = findViewById(R.id.status_divider);
mStatusRevoked = findViewById(R.id.view_key_revoked);
mStatusExpired = findViewById(R.id.view_key_expired);
mViewPager = (ViewPager) findViewById(R.id.view_key_pager);
mSlidingTabLayout = (SlidingTabLayout) findViewById(R.id.view_key_sliding_tab_layout);
@@ -363,10 +372,14 @@ public class ViewKeyActivity extends ActionBarActivity implements
KeychainContract.KeyRings._ID,
KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.KeyRings.USER_ID,
KeychainContract.KeyRings.IS_REVOKED,
KeychainContract.KeyRings.EXPIRY,
};
static final int INDEX_UNIFIED_MASTER_KEY_ID = 1;
static final int INDEX_UNIFIED_USER_ID = 2;
static final int INDEX_UNIFIED_IS_REVOKED = 3;
static final int INDEX_UNIFIED_EXPIRY = 4;
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
@@ -408,6 +421,24 @@ public class ViewKeyActivity extends ActionBarActivity implements
String keyIdStr = PgpKeyHelper.convertKeyIdToHex(masterKeyId);
getSupportActionBar().setSubtitle(keyIdStr);
// If this key is revoked, it cannot be used for anything!
if (data.getInt(INDEX_UNIFIED_IS_REVOKED) != 0) {
mStatusDivider.setVisibility(View.VISIBLE);
mStatusRevoked.setVisibility(View.VISIBLE);
mStatusExpired.setVisibility(View.GONE);
} else {
mStatusRevoked.setVisibility(View.GONE);
Date expiryDate = new Date(data.getLong(INDEX_UNIFIED_EXPIRY) * 1000);
if (!data.isNull(INDEX_UNIFIED_EXPIRY) && expiryDate.before(new Date())) {
mStatusDivider.setVisibility(View.VISIBLE);
mStatusExpired.setVisibility(View.VISIBLE);
} else {
mStatusDivider.setVisibility(View.GONE);
mStatusExpired.setVisibility(View.GONE);
}
}
break;
}
}

View File

@@ -32,6 +32,8 @@ import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ListView;
import com.devspark.appmsg.AppMsg;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
@@ -49,8 +51,6 @@ public class ViewKeyMainFragment extends Fragment implements
public static final String ARG_DATA_URI = "uri";
private LinearLayout mContainer;
private View mStatusRevoked;
private View mStatusExpired;
private View mActionEdit;
private View mActionEditDivider;
private View mActionEncrypt;
@@ -62,6 +62,9 @@ public class ViewKeyMainFragment extends Fragment implements
private static final int LOADER_ID_UNIFIED = 0;
private static final int LOADER_ID_USER_IDS = 1;
// conservative attitude
private boolean mHasEncrypt = true;
private ViewKeyUserIdsAdapter mUserIdsAdapter;
private Uri mDataUri;
@@ -72,8 +75,6 @@ public class ViewKeyMainFragment extends Fragment implements
mContainer = (LinearLayout) view.findViewById(R.id.container);
mUserIds = (ListView) view.findViewById(R.id.view_key_user_ids);
mStatusRevoked = view.findViewById(R.id.view_key_revoked);
mStatusExpired = view.findViewById(R.id.view_key_expired);
mActionEdit = view.findViewById(R.id.view_key_action_edit);
mActionEditDivider = view.findViewById(R.id.view_key_action_edit_divider);
mActionEncrypt = view.findViewById(R.id.view_key_action_encrypt);
@@ -132,30 +133,14 @@ public class ViewKeyMainFragment extends Fragment implements
}
static final String[] UNIFIED_PROJECTION = new String[]{
KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET, KeyRings.IS_REVOKED,
KeyRings.USER_ID, KeyRings.FINGERPRINT,
KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.EXPIRY,
KeyRings.HAS_ENCRYPT
KeyRings._ID, KeyRings.MASTER_KEY_ID,
KeyRings.HAS_ANY_SECRET, KeyRings.IS_REVOKED, KeyRings.EXPIRY, KeyRings.HAS_ENCRYPT
};
static final int INDEX_UNIFIED_MASTER_KEY_ID = 1;
static final int INDEX_UNIFIED_HAS_ANY_SECRET = 2;
static final int INDEX_UNIFIED_IS_REVOKED = 3;
static final int INDEX_UNIFIED_USER_ID = 4;
static final int INDEX_UNIFIED_FINGERPRINT = 5;
static final int INDEX_UNIFIED_ALGORITHM = 6;
static final int INDEX_UNIFIED_KEY_SIZE = 7;
static final int INDEX_UNIFIED_CREATION = 8;
static final int INDEX_UNIFIED_EXPIRY = 9;
static final int INDEX_UNIFIED_HAS_ENCRYPT = 10;
static final String[] KEYS_PROJECTION = new String[]{
Keys._ID,
Keys.KEY_ID, Keys.RANK, Keys.ALGORITHM, Keys.KEY_SIZE, Keys.HAS_SECRET,
Keys.CAN_CERTIFY, Keys.CAN_ENCRYPT, Keys.CAN_SIGN, Keys.IS_REVOKED,
Keys.CREATION, Keys.EXPIRY, Keys.FINGERPRINT
};
static final int KEYS_INDEX_CAN_ENCRYPT = 7;
static final int INDEX_UNIFIED_EXPIRY = 4;
static final int INDEX_UNIFIED_HAS_ENCRYPT = 5;
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch (id) {
@@ -165,7 +150,8 @@ public class ViewKeyMainFragment extends Fragment implements
}
case LOADER_ID_USER_IDS: {
Uri baseUri = UserIds.buildUserIdsUri(mDataUri);
return new CursorLoader(getActivity(), baseUri, ViewKeyUserIdsAdapter.USER_IDS_PROJECTION, null, null, null);
return new CursorLoader(getActivity(), baseUri,
ViewKeyUserIdsAdapter.USER_IDS_PROJECTION, null, null, null);
}
default:
@@ -206,9 +192,6 @@ public class ViewKeyMainFragment extends Fragment implements
// If this key is revoked, it cannot be used for anything!
if (data.getInt(INDEX_UNIFIED_IS_REVOKED) != 0) {
mStatusRevoked.setVisibility(View.VISIBLE);
mStatusExpired.setVisibility(View.GONE);
mActionEdit.setEnabled(false);
mActionCertify.setEnabled(false);
mActionEncrypt.setEnabled(false);
@@ -217,18 +200,16 @@ public class ViewKeyMainFragment extends Fragment implements
Date expiryDate = new Date(data.getLong(INDEX_UNIFIED_EXPIRY) * 1000);
if (!data.isNull(INDEX_UNIFIED_EXPIRY) && expiryDate.before(new Date())) {
mStatusRevoked.setVisibility(View.GONE);
mStatusExpired.setVisibility(View.VISIBLE);
mActionCertify.setEnabled(false);
mActionEncrypt.setEnabled(false);
} else {
mStatusRevoked.setVisibility(View.GONE);
mStatusExpired.setVisibility(View.GONE);
mActionCertify.setEnabled(true);
mActionEncrypt.setEnabled(true);
}
}
mHasEncrypt = data.getInt(INDEX_UNIFIED_HAS_ENCRYPT) != 0;
break;
}
}
@@ -255,6 +236,11 @@ public class ViewKeyMainFragment extends Fragment implements
}
private void encrypt(Uri dataUri) {
// If there is no encryption key, don't bother.
if (!mHasEncrypt) {
AppMsg.makeText(getActivity(), R.string.error_no_encrypt_subkey, AppMsg.STYLE_ALERT).show();
return;
}
try {
long keyId = new ProviderHelper(getActivity()).extractOrGetMasterKeyId(dataUri);
long[] encryptionKeyIds = new long[]{keyId};