diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org')
10 files changed, 108 insertions, 30 deletions
| diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index 8f6b7a758..47e897d6c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -42,6 +42,7 @@ public class KeychainContract {          String CAN_ENCRYPT = "can_encrypt";          String CAN_CERTIFY = "can_certify";          String IS_REVOKED = "is_revoked"; +        String HAS_SECRET = "has_secret";          String CREATION = "creation";          String EXPIRY = "expiry"; @@ -106,7 +107,7 @@ public class KeychainContract {          public static final String MASTER_KEY_ID = KeysColumns.MASTER_KEY_ID;          public static final String IS_REVOKED = KeysColumns.IS_REVOKED;          public static final String VERIFIED = CertsColumns.VERIFIED; -        public static final String HAS_SECRET = "has_secret"; +        public static final String HAS_ANY_SECRET = "has_any_secret";          public static final String HAS_ENCRYPT = "has_encrypt";          public static final String HAS_SIGN = "has_encrypt"; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 614b166d6..2cd0427b1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -84,6 +84,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {                  + KeysColumns.CAN_SIGN + " BOOLEAN, "                  + KeysColumns.CAN_ENCRYPT + " BOOLEAN, "                  + KeysColumns.IS_REVOKED + " BOOLEAN, " +                + KeysColumns.HAS_SECRET + " BOOLEAN, "                  + KeysColumns.CREATION + " INTEGER, "                  + KeysColumns.EXPIRY + " INTEGER, " @@ -187,6 +188,11 @@ public class KeychainDatabase extends SQLiteOpenHelper {          if (!db.isReadOnly()) {              // Enable foreign key constraints              db.execSQL("PRAGMA foreign_keys=ON;"); +            // TODO this is a dev hack, remove for release! +            try { +                db.execSQL("ALTER TABLE keys ADD COLUMN has_secret BOOLEAN"); +            } catch(Exception e) { +            }          }      } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 1ad42b13a..a201db342 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -254,16 +254,18 @@ public class KeychainProvider extends ContentProvider {                  projectionMap.put(KeyRings.FINGERPRINT, Keys.FINGERPRINT);                  projectionMap.put(KeyRings.USER_ID, UserIds.USER_ID);                  projectionMap.put(KeyRings.VERIFIED, KeyRings.VERIFIED); -                projectionMap.put(KeyRings.HAS_SECRET, +                projectionMap.put(KeyRings.HAS_SECRET, KeyRings.HAS_SECRET); +                projectionMap.put(KeyRings.HAS_ANY_SECRET,                      "(EXISTS (SELECT * FROM " + Tables.KEY_RINGS_SECRET                          + " WHERE " + Tables.KEY_RINGS_SECRET + "." + KeyRingData.MASTER_KEY_ID                              + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID -                        + ")) AS " + KeyRings.HAS_SECRET); +                        + ")) AS " + KeyRings.HAS_ANY_SECRET);                  projectionMap.put(KeyRings.HAS_ENCRYPT,                      "(EXISTS (SELECT COUNT(*) FROM " + Tables.KEYS + " AS k"                          +" WHERE k." + Keys.MASTER_KEY_ID                              + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID                          + " AND k." + Keys.IS_REVOKED + " = 0" +                        + " AND k." + Keys.HAS_SECRET + " = 1"                          + " AND k." + Keys.CAN_ENCRYPT + " = 1"                          + " AND ( k." + Keys.EXPIRY + " IS NULL OR k." + Keys.EXPIRY                              + " >= '" + new Date().getTime() / 1000 + "' )" @@ -273,6 +275,7 @@ public class KeychainProvider extends ContentProvider {                                  +" WHERE k." + Keys.MASTER_KEY_ID                                  + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID                                  + " AND k." + Keys.IS_REVOKED + " = 0" +                                + " AND k." + Keys.HAS_SECRET + " = 1"                                  + " AND k." + Keys.CAN_SIGN + " = 1"                                  + " AND ( k." + Keys.EXPIRY + " IS NULL OR k." + Keys.EXPIRY                                  + " >= '" + new Date().getTime() / 1000 + "' )" @@ -373,6 +376,7 @@ public class KeychainProvider extends ContentProvider {                  projectionMap.put(Keys.CAN_CERTIFY, Keys.CAN_CERTIFY);                  projectionMap.put(Keys.CAN_ENCRYPT, Keys.CAN_ENCRYPT);                  projectionMap.put(Keys.CAN_SIGN, Keys.CAN_SIGN); +                projectionMap.put(Keys.HAS_SECRET, Keys.HAS_SECRET);                  projectionMap.put(Keys.CREATION, Keys.CREATION);                  projectionMap.put(Keys.EXPIRY, Keys.EXPIRY);                  projectionMap.put(Keys.ALGORITHM, Keys.ALGORITHM); @@ -699,6 +703,20 @@ public class KeychainProvider extends ContentProvider {          try {              final int match = mUriMatcher.match(uri);              switch (match) { +                case KEY_RING_KEYS: { +                    if (values.size() != 1 || !values.containsKey(Keys.HAS_SECRET)) { +                        throw new UnsupportedOperationException( +                                "Only has_secret column may be updated!"); +                    } +                    // make sure we get a long value here +                    Long mkid = Long.parseLong(uri.getPathSegments().get(1)); +                    String actualSelection = Keys.MASTER_KEY_ID + " = " + Long.toString(mkid); +                    if (!TextUtils.isEmpty(selection)) { +                        actualSelection += " AND (" + selection + ")"; +                    } +                    count = db.update(Tables.KEYS, values, actualSelection, selectionArgs); +                    break; +                }                  case API_APPS_BY_PACKAGE_NAME:                      count = db.update(Tables.API_APPS, values,                              buildDefaultApiAppsSelection(uri, selection), selectionArgs); @@ -715,7 +733,7 @@ public class KeychainProvider extends ContentProvider {              getContext().getContentResolver().notifyChange(uri, null);          } catch (SQLiteConstraintException e) { -            Log.e(Constants.TAG, "Constraint exception on update! Entry already existing?"); +            Log.e(Constants.TAG, "Constraint exception on update! Entry already existing?", e);          }          return count; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 1da4ffe55..01e95343d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -28,12 +28,15 @@ import android.net.Uri;  import android.os.RemoteException;  import org.spongycastle.bcpg.ArmoredOutputStream; +import org.spongycastle.bcpg.S2K;  import org.spongycastle.openpgp.PGPException;  import org.spongycastle.openpgp.PGPKeyRing;  import org.spongycastle.openpgp.PGPPublicKey;  import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPSecretKey;  import org.spongycastle.openpgp.PGPSecretKeyRing;  import org.spongycastle.openpgp.PGPSignature; +import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;  import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;  import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; @@ -387,13 +390,38 @@ public class ProviderHelper {      public void saveKeyRing(PGPSecretKeyRing keyRing) throws IOException {          long masterKeyId = keyRing.getPublicKey().getKeyID(); +        { +            Uri uri = Keys.buildKeysUri(Long.toString(masterKeyId)); + +            // first, mark all keys as not available +            ContentValues values = new ContentValues(); +            values.put(Keys.HAS_SECRET, 0); +            mContentResolver.update(uri, values, null, null); + +            values.put(Keys.HAS_SECRET, 1); +            // then, mark exactly the keys we have available +            for (PGPSecretKey sub : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) { +                // Set to 1, except if the encryption type is GNU_DUMMY_S2K +                if(sub.getS2K().getType() != S2K.GNU_DUMMY_S2K) { +                    mContentResolver.update(uri, values, Keys.KEY_ID + " = ?", new String[]{ +                            Long.toString(sub.getKeyID()) +                    }); +                } +            } +            // this implicitly leaves all keys which were not in the secret key ring +            // with has_secret = 0 +        } +          // save secret keyring -        ContentValues values = new ContentValues(); -        values.put(KeyRingData.MASTER_KEY_ID, masterKeyId); -        values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded()); -        // insert new version of this keyRing -        Uri uri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId)); -        mContentResolver.insert(uri, values); +        { +            ContentValues values = new ContentValues(); +            values.put(KeyRingData.MASTER_KEY_ID, masterKeyId); +            values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded()); +            // insert new version of this keyRing +            Uri uri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId)); +            mContentResolver.insert(uri, values); +        } +      }      /** diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index bb54a9fe0..c883dee0e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -685,7 +685,7 @@ public class KeychainIntentService extends IntentService                  }                  Cursor cursor = getContentResolver().query(KeyRings.buildUnifiedKeyRingsUri(), -                        new String[]{KeyRings.MASTER_KEY_ID, KeyRings.HAS_SECRET}, +                        new String[]{KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET},                          selection, null, null);                  try {                      cursor.moveToFirst(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index c60acf9a2..2cc3396ec 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -256,7 +256,7 @@ public class KeyListFragment extends Fragment              KeyRings.IS_REVOKED,              KeyRings.EXPIRY,              KeyRings.VERIFIED, -            KeyRings.HAS_SECRET +            KeyRings.HAS_ANY_SECRET      };      static final int INDEX_MASTER_KEY_ID = 1; @@ -264,10 +264,10 @@ public class KeyListFragment extends Fragment      static final int INDEX_IS_REVOKED = 3;      static final int INDEX_EXPIRY = 4;      static final int INDEX_VERIFIED = 5; -    static final int INDEX_HAS_SECRET = 6; +    static final int INDEX_HAS_ANY_SECRET = 6;      static final String ORDER = // IN THE COURT -            KeyRings.HAS_SECRET + " DESC, " + KeyRings.USER_ID + " ASC"; +            KeyRings.HAS_ANY_SECRET + " DESC, " + KeyRings.USER_ID + " ASC";      @Override @@ -518,7 +518,7 @@ public class KeyListFragment extends Fragment              { // set edit button and revoked info, specific by key type -                if (cursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) { +                if (cursor.getInt(KeyListFragment.INDEX_HAS_ANY_SECRET) != 0) {                      // this is a secret key - show the edit mButton                      h.mStatusDivider.setVisibility(View.VISIBLE);                      h.mStatusLayout.setVisibility(View.VISIBLE); @@ -564,7 +564,7 @@ public class KeyListFragment extends Fragment                  throw new IllegalStateException("couldn't move cursor to position " + id);              } -            return mCursor.getInt(INDEX_HAS_SECRET) != 0; +            return mCursor.getInt(INDEX_HAS_ANY_SECRET) != 0;          }          public long getMasterKeyId(int id) {              if (!mCursor.moveToPosition(id)) { @@ -604,7 +604,7 @@ public class KeyListFragment extends Fragment                  throw new IllegalStateException("couldn't move cursor to position " + position);              } -            if (mCursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) { +            if (mCursor.getInt(KeyListFragment.INDEX_HAS_ANY_SECRET) != 0) {                  { // set contact count                      int num = mCursor.getCount();                      String contactsTotal = getResources().getQuantityString(R.plurals.n_contacts, num, num); @@ -643,7 +643,7 @@ public class KeyListFragment extends Fragment              }              // early breakout: all secret keys are assigned id 0 -            if (mCursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) { +            if (mCursor.getInt(KeyListFragment.INDEX_HAS_ANY_SECRET) != 0) {                  return 1L;              }              // otherwise, return the first character of the name as ID diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java index 47f4f52d7..118449b9b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java @@ -117,10 +117,11 @@ public class SelectSecretKeyFragment extends ListFragment implements                  KeyRings.IS_REVOKED,                  KeyRings.CAN_CERTIFY,                  KeyRings.HAS_SIGN, -                KeyRings.HAS_SECRET +                KeyRings.HAS_SECRET, +                KeyRings.HAS_ANY_SECRET          }; -        String where = KeyRings.HAS_SECRET + " = 1"; +        String where = KeyRings.HAS_ANY_SECRET + " = 1";          // Now create and return a CursorLoader that will take care of          // creating a Cursor for the data being displayed. @@ -151,7 +152,7 @@ public class SelectSecretKeyFragment extends ListFragment implements      private class SelectSecretKeyCursorAdapter extends SelectKeyCursorAdapter { -        private int mIndexHasSign, mIndexCanCertify; +        private int mIndexHasSecret, mIndexHasSign, mIndexCanCertify;          public SelectSecretKeyCursorAdapter(Context context, Cursor c, int flags, ListView listView) {              super(context, c, flags, listView); @@ -161,6 +162,7 @@ public class SelectSecretKeyFragment extends ListFragment implements          protected void initIndex(Cursor cursor) {              super.initIndex(cursor);              if (cursor != null) { +                mIndexHasSecret = cursor.getColumnIndexOrThrow(KeyRings.HAS_SECRET);                  mIndexCanCertify = cursor.getColumnIndexOrThrow(KeyRings.CAN_CERTIFY);                  mIndexHasSign = cursor.getColumnIndexOrThrow(KeyRings.HAS_SIGN);              } @@ -177,8 +179,10 @@ public class SelectSecretKeyFragment extends ListFragment implements              // Special from superclass: Te              boolean enabled = false;              if((Boolean) h.status.getTag()) { +                if (cursor.getInt(mIndexHasSecret) == 0) { +                    h.status.setText(R.string.no_subkey);                  // Check if key is viable for our purposes (certify or sign) -                if(mFilterCertify) { +                } else if(mFilterCertify) {                      if (cursor.getInt(mIndexCanCertify) == 0) {                          h.status.setText(R.string.can_certify_not);                      } else { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index 89f6a467b..39eceda81 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -158,13 +158,13 @@ public class ViewKeyMainFragment extends Fragment implements      }      static final String[] UNIFIED_PROJECTION = new String[] { -        KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_SECRET, +        KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET,              KeyRings.USER_ID, KeyRings.FINGERPRINT,              KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.EXPIRY,      };      static final int INDEX_UNIFIED_MKI = 1; -    static final int INDEX_UNIFIED_HAS_SECRET = 2; +    static final int INDEX_UNIFIED_HAS_ANY_SECRET = 2;      static final int INDEX_UNIFIED_UID = 3;      static final int INDEX_UNIFIED_FINGERPRINT = 4;      static final int INDEX_UNIFIED_ALGORITHM = 5; @@ -174,11 +174,11 @@ public class ViewKeyMainFragment extends Fragment implements      static final String[] KEYS_PROJECTION = new String[] {              Keys._ID, -            Keys.KEY_ID, Keys.RANK, Keys.ALGORITHM, Keys.KEY_SIZE, +            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 = 6; +    static final int KEYS_INDEX_CAN_ENCRYPT = 7;      public Loader<Cursor> onCreateLoader(int id, Bundle args) {          switch (id) { @@ -225,7 +225,7 @@ public class ViewKeyMainFragment extends Fragment implements                      mEmail.setText(mainUserId[1]);                      mComment.setText(mainUserId[2]); -                    if (data.getInt(INDEX_UNIFIED_HAS_SECRET) != 0) { +                    if (data.getInt(INDEX_UNIFIED_HAS_ANY_SECRET) != 0) {                          mSecretKey.setTextColor(getResources().getColor(R.color.emphasis));                          mSecretKey.setText(R.string.secret_key_yes); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java index 534fbfb02..27ba19233 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java @@ -45,9 +45,12 @@ public class ViewKeyKeysAdapter extends CursorAdapter {      private int mIndexCanCertify;      private int mIndexCanEncrypt;      private int mIndexCanSign; +    private int mIndexHasSecret;      private int mIndexRevokedKey;      private int mIndexExpiry; +    private boolean hasAnySecret; +      private ColorStateList mDefaultTextColor;      public ViewKeyKeysAdapter(Context context, Cursor c, int flags) { @@ -62,6 +65,17 @@ public class ViewKeyKeysAdapter extends CursorAdapter {      public Cursor swapCursor(Cursor newCursor) {          initIndex(newCursor); +        hasAnySecret = false; +        if (newCursor != null) { +            newCursor.moveToFirst(); +            do { +                if (newCursor.getInt(mIndexHasSecret) != 0) { +                    hasAnySecret = true; +                    break; +                } +            } while(newCursor.moveToNext()); +        } +          return super.swapCursor(newCursor);      } @@ -80,6 +94,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter {              mIndexCanCertify = cursor.getColumnIndexOrThrow(Keys.CAN_CERTIFY);              mIndexCanEncrypt = cursor.getColumnIndexOrThrow(Keys.CAN_ENCRYPT);              mIndexCanSign = cursor.getColumnIndexOrThrow(Keys.CAN_SIGN); +            mIndexHasSecret = cursor.getColumnIndexOrThrow(Keys.HAS_SECRET);              mIndexRevokedKey = cursor.getColumnIndexOrThrow(Keys.IS_REVOKED);              mIndexExpiry = cursor.getColumnIndexOrThrow(Keys.EXPIRY);          } @@ -101,7 +116,13 @@ public class ViewKeyKeysAdapter extends CursorAdapter {                  cursor.getInt(mIndexKeySize));          keyId.setText(keyIdStr); -        keyDetails.setText("(" + algorithmStr + ")"); +        // may be set with additional "stripped" later on +        if (hasAnySecret && cursor.getInt(mIndexHasSecret) == 0) { +            keyDetails.setText("(" + algorithmStr + ", " + +                    context.getString(R.string.key_stripped) + ")"); +        } else { +            keyDetails.setText("(" + algorithmStr + ")"); +        }          if (cursor.getInt(mIndexRank) == 0) {              masterKeyIcon.setVisibility(View.INVISIBLE); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index 7b4a7be83..14f7b6810 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -91,10 +91,10 @@ public class DeleteKeyDialogFragment extends DialogFragment {              HashMap<String, Object> data = new ProviderHelper(activity).getUnifiedData(masterKeyId, new String[]{                      KeyRings.USER_ID, -                    KeyRings.HAS_SECRET +                    KeyRings.HAS_ANY_SECRET              }, new int[]{ProviderHelper.FIELD_TYPE_STRING, ProviderHelper.FIELD_TYPE_INTEGER});              String userId = (String) data.get(KeyRings.USER_ID); -            boolean hasSecret = ((Long) data.get(KeyRings.HAS_SECRET)) == 1; +            boolean hasSecret = ((Long) data.get(KeyRings.HAS_ANY_SECRET)) == 1;              // Set message depending on which key it is.              mMainMessage.setText(getString( | 
