diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 653129bd3b..2477ed09b5 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -73,12 +73,15 @@ android:windowSoftInputMode="stateVisible" android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout"/> + + - diff --git a/res/layout/identity_key_view.xml b/res/layout/identity_key_view.xml index 891968451f..a7992d186a 100644 --- a/res/layout/identity_key_view.xml +++ b/res/layout/identity_key_view.xml @@ -3,35 +3,18 @@ android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:orientation="horizontal" - android:paddingRight="10dip"> + android:padding="15dip"> - - - - - + - \ No newline at end of file diff --git a/res/layout/review_identities.xml b/res/layout/review_identities.xml index 177ca920ab..4cb3178276 100644 --- a/res/layout/review_identities.xml +++ b/res/layout/review_identities.xml @@ -1,22 +1,24 @@ + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" + android:paddingLeft="16dip" + android:paddingRight="16dip"> - - - + + + \ No newline at end of file diff --git a/res/layout/view_identity_activity.xml b/res/layout/view_identity_activity.xml index 162612bd21..2c6050ccdf 100644 --- a/res/layout/view_identity_activity.xml +++ b/res/layout/view_identity_activity.xml @@ -1,7 +1,9 @@ + android:layout_height="fill_parent" + android:layout_marginLeft="16dip" + android:layout_marginRight="16dip"> + android:textAppearance="?android:attr/textAppearanceMedium" + android:text="Identity:" + android:layout_marginRight="7dip" /> diff --git a/src/org/thoughtcrime/securesms/IdentityKeyView.java b/src/org/thoughtcrime/securesms/IdentityKeyView.java index 893b87a8c1..17691c06d5 100644 --- a/src/org/thoughtcrime/securesms/IdentityKeyView.java +++ b/src/org/thoughtcrime/securesms/IdentityKeyView.java @@ -1,6 +1,6 @@ -/** +/** * Copyright (C) 2011 Whisper Systems - * + * * 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 @@ -10,7 +10,7 @@ * 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 . */ @@ -19,45 +19,43 @@ package org.thoughtcrime.securesms; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; -import android.view.View; -import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; /** - * Activity for displaying user identity keys. - * + * List item view for displaying user identity keys. + * * @author Moxie Marlinspike */ public class IdentityKeyView extends RelativeLayout { - + private TextView identityName; - private ImageView validImage; - private ImageView invalidImage; - + private String identityKeyString; + public IdentityKeyView(Context context) { super(context); - + LayoutInflater li = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); li.inflate(R.layout.identity_key_view, this, true); - + initializeResources(); } - + public IdentityKeyView(Context context, AttributeSet attributeSet) { super(context, attributeSet); } - - public void set(String name, boolean valid) { + + public void set(String name, String identityKeyString) { identityName.setText(name); - validImage.setVisibility(valid ? View.VISIBLE : View.GONE); - invalidImage.setVisibility(valid ? View.GONE : View.VISIBLE); + this.identityKeyString = identityKeyString; } - + + public String getIdentityKeyString() { + return this.identityKeyString; + } + private void initializeResources() { this.identityName = (TextView)findViewById(R.id.identity_name); - this.validImage = (ImageView)findViewById(R.id.valid_indicator); - this.invalidImage = (ImageView)findViewById(R.id.invalid_indicator); } } diff --git a/src/org/thoughtcrime/securesms/ReviewIdentitiesActivity.java b/src/org/thoughtcrime/securesms/ReviewIdentitiesActivity.java index 28a40abc5e..4a7c0b75cd 100644 --- a/src/org/thoughtcrime/securesms/ReviewIdentitiesActivity.java +++ b/src/org/thoughtcrime/securesms/ReviewIdentitiesActivity.java @@ -1,6 +1,6 @@ -/** +/** * Copyright (C) 2011 Whisper Systems - * + * * 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 @@ -10,13 +10,30 @@ * 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 . */ package org.thoughtcrime.securesms; -import java.io.IOException; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.Intent; +import android.database.Cursor; +import android.os.Bundle; +import android.util.Log; +import android.view.ContextMenu; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CursorAdapter; +import android.widget.ListView; +import android.widget.Toast; + +import com.actionbarsherlock.app.SherlockListActivity; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; import org.thoughtcrime.securesms.crypto.IdentityKey; import org.thoughtcrime.securesms.crypto.InvalidKeyException; @@ -27,45 +44,30 @@ import org.thoughtcrime.securesms.database.IdentityDatabase; import org.thoughtcrime.securesms.util.Base64; import org.thoughtcrime.securesms.util.MemoryCleaner; -import android.app.AlertDialog; -import android.app.ListActivity; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.database.Cursor; -import android.os.Bundle; -import android.util.Log; -import android.view.ContextMenu; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CursorAdapter; -import android.widget.Toast; +import java.io.IOException; /** * Activity for reviewing/managing saved identity keys. - * + * * @author Moxie Marlinspike */ -public class ReviewIdentitiesActivity extends ListActivity { +public class ReviewIdentitiesActivity extends SherlockListActivity { - private static final int MENU_OPTION_VIEW = 1; private static final int MENU_OPTION_DELETE = 2; - + private MasterSecret masterSecret; private MasterCipher masterCipher; - + @Override public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + super.onCreate(savedInstanceState); this.setContentView(R.layout.review_identities); - + this.getSupportActionBar().setDisplayHomeAsUpEnabled(true); + initializeResources(); registerForContextMenu(this.getListView()); } - + @Override protected void onDestroy() { masterCipher = null; @@ -73,36 +75,46 @@ public class ReviewIdentitiesActivity extends ListActivity { MemoryCleaner.clean(masterSecret); super.onDestroy(); } - + + @Override + public void onListItemClick(ListView listView, View view, int position, long id) { + viewIdentity(((IdentityKeyView)view).getIdentityKeyString()); + } + @Override public void onCreateContextMenu (ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { - menu.add(0, MENU_OPTION_VIEW, Menu.NONE, "View Key"); menu.add(0, MENU_OPTION_DELETE, Menu.NONE, "Delete"); } @Override - public boolean onContextItemSelected(MenuItem item) { + public boolean onContextItemSelected(android.view.MenuItem item) { Cursor cursor = ((CursorAdapter)this.getListAdapter()).getCursor(); String identityKeyString = cursor.getString(cursor.getColumnIndexOrThrow(IdentityDatabase.IDENTITY_KEY)); String identityName = cursor.getString(cursor.getColumnIndexOrThrow(IdentityDatabase.IDENTITY_NAME)); - - + + switch(item.getItemId()) { case MENU_OPTION_DELETE: deleteIdentity(identityName, identityKeyString); return true; - case MENU_OPTION_VIEW: - viewIdentity(identityKeyString); - return true; } return false; } - + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: finish(); return true; + } + + return false; + } + + private void initializeResources() { this.masterSecret = (MasterSecret)getIntent().getParcelableExtra("master_secret"); this.masterCipher = new MasterCipher(masterSecret); - + Cursor cursor = DatabaseFactory.getIdentityDatabase(this).getIdentities(); this.startManagingCursor(cursor); this.setListAdapter(new IdentitiesListAdapter(this, cursor)); @@ -121,7 +133,7 @@ public class ReviewIdentitiesActivity extends ListActivity { Toast.makeText(this, "Unable to view corrupted identity key!", Toast.LENGTH_LONG).show(); } } - + private void deleteIdentity(String name, String keyString) { AlertDialog.Builder alertDialog = new AlertDialog.Builder(this); alertDialog.setTitle("Delete identity?"); @@ -131,23 +143,24 @@ public class ReviewIdentitiesActivity extends ListActivity { alertDialog.setPositiveButton(R.string.yes, new DeleteIdentityListener(name, keyString)); alertDialog.show(); } - + private class DeleteIdentityListener implements OnClickListener { private final String name; private final String keyString; - + public DeleteIdentityListener(String name, String keyString) { this.name = name; this.keyString = keyString; } - + public void onClick(DialogInterface arg0, int arg1) { - DatabaseFactory.getIdentityDatabase(ReviewIdentitiesActivity.this).deleteIdentity(name, keyString); + DatabaseFactory.getIdentityDatabase(ReviewIdentitiesActivity.this) + .deleteIdentity(name, keyString); } } - + private class IdentitiesListAdapter extends CursorAdapter { - + public IdentitiesListAdapter(Context context, Cursor cursor) { super(context, cursor); } @@ -160,13 +173,13 @@ public class ReviewIdentitiesActivity extends ListActivity { public void bindView(View view, Context context, Cursor cursor) { IdentityKey identityKey; boolean valid; - + String identityKeyString = cursor.getString(cursor.getColumnIndexOrThrow(IdentityDatabase.IDENTITY_KEY)); String identityName = cursor.getString(cursor.getColumnIndexOrThrow(IdentityDatabase.IDENTITY_NAME)); - try { + try { String mac = cursor.getString(cursor.getColumnIndexOrThrow(IdentityDatabase.MAC)); - valid = masterCipher.verifyMacFor(identityName + identityKeyString, Base64.decode(mac)); + valid = masterCipher.verifyMacFor(identityName + identityKeyString, Base64.decode(mac)); identityKey = new IdentityKey(Base64.decode(identityKeyString), 0); } catch (InvalidKeyException ike) { Log.w("ReviewIdentitiesActivity",ike); @@ -176,7 +189,10 @@ public class ReviewIdentitiesActivity extends ListActivity { valid = false; } - ((IdentityKeyView)view).set(identityName, valid); + if (!valid) + identityName = "Invalid Identity!"; + + ((IdentityKeyView)view).set(identityName, identityKeyString); } @Override