using proper PreferenceActivity now, tho the underlying storage of the values remained almost the same, some changes how the preferences are accessed and how the cache service is started

This commit is contained in:
Thialfihar 2010-06-17 13:23:07 +00:00
parent 865c998abd
commit 1bad192a91
16 changed files with 529 additions and 481 deletions

View File

@ -1,4 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"

View File

@ -1,4 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@ -1,4 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ScrollView <ScrollView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@ -1,4 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"

View File

@ -1,197 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingTop="5dip"
android:layout_marginRight="?android:attr/scrollbarSize">
<TextView
android:id="@+id/section_general"
android:text="@string/section_general"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="?android:attr/listDivider"
android:layout_marginBottom="5dip"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/label_passPhraseCacheTtl"
android:text="@string/label_passPhraseCacheTtl"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"/>
<Spinner
android:id="@+id/passPhraseCacheTtl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<TextView
android:id="@+id/section_defaults"
android:text="@string/section_defaults"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="?android:attr/listDivider"
android:layout_marginBottom="5dip"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/label_encryptionAlgorithm"
android:text="@string/label_encryptionAlgorithm"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"/>
<Spinner
android:id="@+id/encryptionAlgorithm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/label_hashAlgorithm"
android:text="@string/label_hashAlgorithm"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"/>
<Spinner
android:id="@+id/hashAlgorithm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/label_messageCompression"
android:text="@string/label_messageCompression"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"/>
<Spinner
android:id="@+id/messageCompression"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/label_fileCompression"
android:text="@string/label_fileCompression"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"/>
<Spinner
android:id="@+id/fileCompression"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/label_asciiArmour"
android:text="@string/label_asciiArmour"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1"/>
<CheckBox
android:id="@+id/asciiArmour"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"/>
</LinearLayout>
</LinearLayout>
</ScrollView>

35
res/values/arrays.xml Normal file
View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string-array name="pass_phrase_cache_ttl_entries">
<item>@string/choice_15secs</item>
<item>@string/choice_1min</item>
<item>@string/choice_3mins</item>
<item>@string/choice_5mins</item>
<item>@string/choice_10mins</item>
</string-array>
<string-array name="pass_phrase_cache_ttl_values">
<item>15</item>
<item>60</item>
<item>180</item>
<item>300</item>
<item>600</item>
</string-array>
</resources>

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/section_general">
<org.thialfihar.android.apg.IntegerListPreference
android:persistent="false"
android:key="passPhraseCacheTtl"
android:entries="@array/pass_phrase_cache_ttl_entries"
android:entryValues="@array/pass_phrase_cache_ttl_values"
android:title="@string/label_passPhraseCacheTtl" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/section_defaults">
<org.thialfihar.android.apg.IntegerListPreference
android:persistent="false"
android:key="defaultEncryptionAlgorithm"
android:title="@string/label_encryptionAlgorithm" />
<org.thialfihar.android.apg.IntegerListPreference
android:persistent="false"
android:key="defaultHashAlgorithm"
android:title="@string/label_hashAlgorithm" />
<org.thialfihar.android.apg.IntegerListPreference
android:persistent="false"
android:key="defaultMessageCompression"
android:title="@string/label_messageCompression" />
<org.thialfihar.android.apg.IntegerListPreference
android:persistent="false"
android:key="defaultFileCompression"
android:title="@string/label_fileCompression" />
<CheckBoxPreference
android:persistent="false"
android:key="defaultAsciiArmour"
android:title="@string/label_asciiArmour" />
</PreferenceCategory>
</PreferenceScreen>

View File

@ -1,4 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<searchable <searchable
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name" android:label="@string/app_name"

View File

@ -1,4 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<searchable <searchable
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name" android:label="@string/app_name"

View File

@ -18,9 +18,6 @@ package org.thialfihar.android.apg;
import java.io.File; import java.io.File;
import org.bouncycastle2.bcpg.HashAlgorithmTags;
import org.bouncycastle2.openpgp.PGPEncryptedData;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
@ -28,7 +25,6 @@ import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Handler; import android.os.Handler;
@ -49,7 +45,8 @@ public class BaseActivity extends Activity
private long mSecretKeyId = 0; private long mSecretKeyId = 0;
private String mDeleteFile = null; private String mDeleteFile = null;
protected static SharedPreferences mPreferences = null;
protected Preferences mPreferences;
private Handler mHandler = new Handler() { private Handler mHandler = new Handler() {
@Override @Override
@ -62,11 +59,9 @@ public class BaseActivity extends Activity
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Apg.initialize(this); mPreferences = Preferences.getPreferences(this);
if (mPreferences == null) { Apg.initialize(this);
mPreferences = getPreferences(MODE_PRIVATE);
}
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File dir = new File(Constants.path.app_dir); File dir = new File(Constants.path.app_dir);
@ -76,9 +71,13 @@ public class BaseActivity extends Activity
} }
} }
Intent intent = new Intent(this, Service.class); startCacheService(this, mPreferences);
intent.putExtra(Service.EXTRA_TTL, getPassPhraseCacheTtl()); }
startService(intent);
public static void startCacheService(Activity activity, Preferences preferences) {
Intent intent = new Intent(activity, Service.class);
intent.putExtra(Service.EXTRA_TTL, preferences.getPassPhraseCacheTtl());
activity.startService(intent);
} }
@Override @Override
@ -372,92 +371,6 @@ public class BaseActivity extends Activity
return mSecretKeyId; return mSecretKeyId;
} }
public int getPassPhraseCacheTtl() {
int ttl = mPreferences.getInt(Constants.pref.pass_phrase_cache_ttl, 180);
// fix the value if it was set to "never" in previous versions, which currently is not
// supported
if (ttl == 0) {
ttl = 180;
setPassPhraseCacheTtl(ttl);
}
return ttl;
}
public void setPassPhraseCacheTtl(int value) {
SharedPreferences.Editor editor = mPreferences.edit();
editor.putInt(Constants.pref.pass_phrase_cache_ttl, value);
editor.commit();
Intent intent = new Intent(this, Service.class);
intent.putExtra(Service.EXTRA_TTL, value);
startService(intent);
}
public int getDefaultEncryptionAlgorithm() {
return mPreferences.getInt(Constants.pref.default_encryption_algorithm,
PGPEncryptedData.AES_256);
}
public void setDefaultEncryptionAlgorithm(int value) {
SharedPreferences.Editor editor = mPreferences.edit();
editor.putInt(Constants.pref.default_encryption_algorithm, value);
editor.commit();
}
public int getDefaultHashAlgorithm() {
return mPreferences.getInt(Constants.pref.default_hash_algorithm,
HashAlgorithmTags.SHA256);
}
public void setDefaultHashAlgorithm(int value) {
SharedPreferences.Editor editor = mPreferences.edit();
editor.putInt(Constants.pref.default_hash_algorithm, value);
editor.commit();
}
public int getDefaultMessageCompression() {
return mPreferences.getInt(Constants.pref.default_message_compression,
Id.choice.compression.zlib);
}
public void setDefaultMessageCompression(int value) {
SharedPreferences.Editor editor = mPreferences.edit();
editor.putInt(Constants.pref.default_message_compression, value);
editor.commit();
}
public int getDefaultFileCompression() {
return mPreferences.getInt(Constants.pref.default_file_compression,
Id.choice.compression.none);
}
public void setDefaultFileCompression(int value) {
SharedPreferences.Editor editor = mPreferences.edit();
editor.putInt(Constants.pref.default_file_compression, value);
editor.commit();
}
public boolean getDefaultAsciiArmour() {
return mPreferences.getBoolean(Constants.pref.default_ascii_armour, false);
}
public void setDefaultAsciiArmour(boolean value) {
SharedPreferences.Editor editor = mPreferences.edit();
editor.putBoolean(Constants.pref.default_ascii_armour, value);
editor.commit();
}
public boolean hasSeenChangeLog() {
return mPreferences.getBoolean(Constants.pref.has_seen_change_log + Apg.getVersion(this),
false);
}
public void setHasSeenChangeLog(boolean value) {
SharedPreferences.Editor editor = mPreferences.edit();
editor.putBoolean(Constants.pref.has_seen_change_log + Apg.getVersion(this), value);
editor.commit();
}
protected void setDeleteFile(String deleteFile) { protected void setDeleteFile(String deleteFile) {
mDeleteFile = deleteFile; mDeleteFile = deleteFile;
} }

View File

@ -213,7 +213,7 @@ public class EncryptActivity extends BaseActivity {
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mFileCompression.setAdapter(adapter); mFileCompression.setAdapter(adapter);
int defaultFileCompression = getDefaultFileCompression(); int defaultFileCompression = mPreferences.getDefaultFileCompression();
for (int i = 0; i < choices.length; ++i) { for (int i = 0; i < choices.length; ++i) {
if (choices[i].getId() == defaultFileCompression) { if (choices[i].getId() == defaultFileCompression) {
mFileCompression.setSelection(i); mFileCompression.setSelection(i);
@ -224,7 +224,7 @@ public class EncryptActivity extends BaseActivity {
mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterEncryption); mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterEncryption);
mAsciiArmour = (CheckBox) findViewById(R.id.asciiArmour); mAsciiArmour = (CheckBox) findViewById(R.id.asciiArmour);
mAsciiArmour.setChecked(getDefaultAsciiArmour()); mAsciiArmour.setChecked(mPreferences.getDefaultAsciiArmour());
mAsciiArmour.setOnClickListener(new OnClickListener() { mAsciiArmour.setOnClickListener(new OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
@ -607,18 +607,19 @@ public class EncryptActivity extends BaseActivity {
size = byteData.length; size = byteData.length;
useAsciiArmour = true; useAsciiArmour = true;
compressionId = getDefaultMessageCompression(); compressionId = mPreferences.getDefaultMessageCompression();
} }
if (signOnly) { if (signOnly) {
Apg.signText(this, in, out, getSecretKeyId(), Apg.signText(this, in, out, getSecretKeyId(),
Apg.getCachedPassPhrase(getSecretKeyId()), Apg.getCachedPassPhrase(getSecretKeyId()),
getDefaultHashAlgorithm(), this); mPreferences.getDefaultHashAlgorithm(), this);
} else { } else {
Apg.encrypt(this, in, out, size, useAsciiArmour, Apg.encrypt(this, in, out, size, useAsciiArmour,
encryptionKeyIds, signatureKeyId, encryptionKeyIds, signatureKeyId,
Apg.getCachedPassPhrase(signatureKeyId), this, Apg.getCachedPassPhrase(signatureKeyId), this,
getDefaultEncryptionAlgorithm(), getDefaultHashAlgorithm(), mPreferences.getDefaultEncryptionAlgorithm(),
mPreferences.getDefaultHashAlgorithm(),
compressionId, passPhrase); compressionId, passPhrase);
} }

View File

@ -0,0 +1,95 @@
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.thialfihar.android.apg;
import android.content.Context;
import android.preference.ListPreference;
import android.util.AttributeSet;
/**
* A list preference which persists its values as integers instead of strings.
* Code reading the values should use
* {@link android.content.SharedPreferences#getInt}.
* When using XML-declared arrays for entry values, the arrays should be regular
* string arrays containing valid integer values.
*
* @author Rodrigo Damazio
*/
public class IntegerListPreference extends ListPreference {
public IntegerListPreference(Context context) {
super(context);
verifyEntryValues(null);
}
public IntegerListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
verifyEntryValues(null);
}
@Override
public void setEntryValues(CharSequence[] entryValues) {
CharSequence[] oldValues = getEntryValues();
super.setEntryValues(entryValues);
verifyEntryValues(oldValues);
}
@Override
public void setEntryValues(int entryValuesResId) {
CharSequence[] oldValues = getEntryValues();
super.setEntryValues(entryValuesResId);
verifyEntryValues(oldValues);
}
@Override
protected String getPersistedString(String defaultReturnValue) {
// During initial load, there's no known default value
int defaultIntegerValue = Integer.MIN_VALUE;
if (defaultReturnValue != null) {
defaultIntegerValue = Integer.parseInt(defaultReturnValue);
}
// When the list preference asks us to read a string, instead read an
// integer.
int value = getPersistedInt(defaultIntegerValue);
return Integer.toString(value);
}
@Override
protected boolean persistString(String value) {
// When asked to save a string, instead save an integer
return persistInt(Integer.parseInt(value));
}
private void verifyEntryValues(CharSequence[] oldValues) {
CharSequence[] entryValues = getEntryValues();
if (entryValues == null) {
return;
}
for (CharSequence entryValue : entryValues) {
try {
Integer.parseInt(entryValue.toString());
} catch (NumberFormatException nfe) {
super.setEntryValues(oldValues);
throw nfe;
}
}
}
}

View File

@ -510,19 +510,6 @@ public class KeyListActivity extends BaseActivity {
qb.appendWhere(")"); qb.appendWhere(")");
} }
<<<<<<< HEAD
String query = qb.buildQuery(new String[] {
KeyRings.TABLE_NAME + "." + KeyRings._ID, // 0
KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 1
UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 2
},
KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?",
new String[] { "" + (mKeyType == Id.type.public_key ?
Id.database.type_public : Id.database.type_secret) },
null, null, UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC", null);
=======
>>>>>>> 1.0.x
mCursor = qb.query(mDatabase, mCursor = qb.query(mDatabase,
new String[] { new String[] {
KeyRings.TABLE_NAME + "." + KeyRings._ID, // 0 KeyRings.TABLE_NAME + "." + KeyRings._ID, // 0

View File

@ -117,7 +117,7 @@ public class MainActivity extends BaseActivity {
}); });
registerForContextMenu(mAccounts); registerForContextMenu(mAccounts);
if (!hasSeenChangeLog()) { if (!mPreferences.hasSeenChangeLog(Apg.getVersion(this))) {
showDialog(Id.dialog.change_log); showDialog(Id.dialog.change_log);
} }
} }
@ -216,9 +216,10 @@ public class MainActivity extends BaseActivity {
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
MainActivity.this.removeDialog(Id.dialog.change_log); MainActivity.this.removeDialog(Id.dialog.change_log);
setHasSeenChangeLog(true); mPreferences.setHasSeenChangeLog(
Apg.getVersion(MainActivity.this), true);
} }
}); });
return alert.create(); return alert.create();
} }

View File

@ -0,0 +1,106 @@
package org.thialfihar.android.apg;
import org.bouncycastle2.bcpg.HashAlgorithmTags;
import org.bouncycastle2.openpgp.PGPEncryptedData;
import android.content.Context;
import android.content.SharedPreferences;
public class Preferences {
private static Preferences mPreferences;
private SharedPreferences mSharedPreferences;
public static synchronized Preferences getPreferences(Context context)
{
if (mPreferences == null) {
mPreferences = new Preferences(context);
}
return mPreferences;
}
private Preferences(Context context)
{
mSharedPreferences = context.getSharedPreferences("APG.main", Context.MODE_PRIVATE);
}
public int getPassPhraseCacheTtl() {
int ttl = mSharedPreferences.getInt(Constants.pref.pass_phrase_cache_ttl, 180);
// fix the value if it was set to "never" in previous versions, which currently is not
// supported
if (ttl == 0) {
ttl = 180;
}
return ttl;
}
public void setPassPhraseCacheTtl(int value) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putInt(Constants.pref.pass_phrase_cache_ttl, value);
editor.commit();
}
public int getDefaultEncryptionAlgorithm() {
return mSharedPreferences.getInt(Constants.pref.default_encryption_algorithm,
PGPEncryptedData.AES_256);
}
public void setDefaultEncryptionAlgorithm(int value) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putInt(Constants.pref.default_encryption_algorithm, value);
editor.commit();
}
public int getDefaultHashAlgorithm() {
return mSharedPreferences.getInt(Constants.pref.default_hash_algorithm,
HashAlgorithmTags.SHA256);
}
public void setDefaultHashAlgorithm(int value) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putInt(Constants.pref.default_hash_algorithm, value);
editor.commit();
}
public int getDefaultMessageCompression() {
return mSharedPreferences.getInt(Constants.pref.default_message_compression,
Id.choice.compression.zlib);
}
public void setDefaultMessageCompression(int value) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putInt(Constants.pref.default_message_compression, value);
editor.commit();
}
public int getDefaultFileCompression() {
return mSharedPreferences.getInt(Constants.pref.default_file_compression,
Id.choice.compression.none);
}
public void setDefaultFileCompression(int value) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putInt(Constants.pref.default_file_compression, value);
editor.commit();
}
public boolean getDefaultAsciiArmour() {
return mSharedPreferences.getBoolean(Constants.pref.default_ascii_armour, false);
}
public void setDefaultAsciiArmour(boolean value) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putBoolean(Constants.pref.default_ascii_armour, value);
editor.commit();
}
public boolean hasSeenChangeLog(String version) {
return mSharedPreferences.getBoolean(Constants.pref.has_seen_change_log + version,
false);
}
public void setHasSeenChangeLog(String version, boolean value) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putBoolean(Constants.pref.has_seen_change_log + version, value);
editor.commit();
}
}

View File

@ -18,202 +18,157 @@ package org.thialfihar.android.apg;
import org.bouncycastle2.bcpg.HashAlgorithmTags; import org.bouncycastle2.bcpg.HashAlgorithmTags;
import org.bouncycastle2.openpgp.PGPEncryptedData; import org.bouncycastle2.openpgp.PGPEncryptedData;
import org.thialfihar.android.apg.utils.Choice;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.preference.CheckBoxPreference;
import android.view.View.OnClickListener; import android.preference.Preference;
import android.widget.AdapterView; import android.preference.PreferenceActivity;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.Spinner;
import android.widget.AdapterView.OnItemSelectedListener;
public class PreferencesActivity extends BaseActivity { public class PreferencesActivity extends PreferenceActivity {
private Spinner mPassPhraseCacheTtl = null; private IntegerListPreference mPassPhraseCacheTtl = null;
private Spinner mEncryptionAlgorithm = null; private IntegerListPreference mEncryptionAlgorithm = null;
private Spinner mHashAlgorithm = null; private IntegerListPreference mHashAlgorithm = null;
private Spinner mMessageCompression = null; private IntegerListPreference mMessageCompression = null;
private Spinner mFileCompression = null; private IntegerListPreference mFileCompression = null;
private CheckBox mAsciiArmour = null; private CheckBoxPreference mAsciiArmour = null;
private Preferences mPreferences;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.preferences);
mPassPhraseCacheTtl = (Spinner) findViewById(R.id.passPhraseCacheTtl); mPreferences = Preferences.getPreferences(this);
Choice choices[] = { addPreferencesFromResource(R.xml.apg_preferences);
new Choice(15, getString(R.string.choice_15secs)),
new Choice(60, getString(R.string.choice_1min)),
new Choice(180, getString(R.string.choice_3mins)),
new Choice(300, getString(R.string.choice_5mins)),
new Choice(600, getString(R.string.choice_10mins)),
};
ArrayAdapter<Choice> adapter =
new ArrayAdapter<Choice>(this, android.R.layout.simple_spinner_item, choices);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mPassPhraseCacheTtl.setAdapter(adapter);
int passPhraseCache = getPassPhraseCacheTtl(); mPassPhraseCacheTtl = (IntegerListPreference) findPreference(Constants.pref.pass_phrase_cache_ttl);
for (int i = 0; i < choices.length; ++i) { mPassPhraseCacheTtl.setValue("" + mPreferences.getPassPhraseCacheTtl());
if (choices[i].getId() == passPhraseCache) { mPassPhraseCacheTtl.setSummary(mPassPhraseCacheTtl.getEntry());
mPassPhraseCacheTtl.setSelection(i); mPassPhraseCacheTtl.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
break; {
} public boolean onPreferenceChange(Preference preference, Object newValue)
} {
mPassPhraseCacheTtl.setValue(newValue.toString());
mPassPhraseCacheTtl.setOnItemSelectedListener(new OnItemSelectedListener() { mPassPhraseCacheTtl.setSummary(mPassPhraseCacheTtl.getEntry());
@Override mPreferences.setPassPhraseCacheTtl(Integer.parseInt(newValue.toString()));
public void onItemSelected(AdapterView<?> adapter, View view, int index, long id) { BaseActivity.startCacheService(PreferencesActivity.this, mPreferences);
setPassPhraseCacheTtl(((Choice) mPassPhraseCacheTtl.getSelectedItem()).getId()); return false;
}
@Override
public void onNothingSelected(AdapterView<?> adapter) {
// nothing to do
} }
}); });
mEncryptionAlgorithm = (Spinner) findViewById(R.id.encryptionAlgorithm); mEncryptionAlgorithm = (IntegerListPreference) findPreference(Constants.pref.default_encryption_algorithm);
choices = new Choice[] { int valueIds[] = {
new Choice(PGPEncryptedData.AES_128, "AES 128"), PGPEncryptedData.AES_128, PGPEncryptedData.AES_192, PGPEncryptedData.AES_256,
new Choice(PGPEncryptedData.AES_192, "AES 192"), PGPEncryptedData.BLOWFISH, PGPEncryptedData.TWOFISH, PGPEncryptedData.CAST5,
new Choice(PGPEncryptedData.AES_256, "AES 256"), PGPEncryptedData.DES, PGPEncryptedData.TRIPLE_DES, PGPEncryptedData.IDEA,
new Choice(PGPEncryptedData.BLOWFISH, "Blowfish"),
new Choice(PGPEncryptedData.TWOFISH, "Twofish"),
new Choice(PGPEncryptedData.CAST5, "CAST5"),
new Choice(PGPEncryptedData.DES, "DES"),
new Choice(PGPEncryptedData.TRIPLE_DES, "Triple DES"),
new Choice(PGPEncryptedData.IDEA, "IDEA"),
}; };
adapter = new ArrayAdapter<Choice>(this, android.R.layout.simple_spinner_item, choices); String entries[] = {
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); "AES-128", "AES-192", "AES-256",
mEncryptionAlgorithm.setAdapter(adapter); "Blowfish", "Twofish", "CAST5",
"DES", "Triple DES", "IDEA",
int defaultEncryptionAlgorithm = getDefaultEncryptionAlgorithm(); };
for (int i = 0; i < choices.length; ++i) { String values[] = new String[valueIds.length];
if (choices[i].getId() == defaultEncryptionAlgorithm) { for (int i = 0; i < values.length; ++i) {
mEncryptionAlgorithm.setSelection(i); values[i] = "" + valueIds[i];
break;
}
} }
mEncryptionAlgorithm.setEntries(entries);
mEncryptionAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() { mEncryptionAlgorithm.setEntryValues(values);
@Override mEncryptionAlgorithm.setValue("" + mPreferences.getDefaultEncryptionAlgorithm());
public void onItemSelected(AdapterView<?> adapter, View view, int index, long id) { mEncryptionAlgorithm.setSummary(mEncryptionAlgorithm.getEntry());
setDefaultEncryptionAlgorithm(((Choice) mEncryptionAlgorithm.getSelectedItem()).getId()); mEncryptionAlgorithm.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
} {
public boolean onPreferenceChange(Preference preference, Object newValue)
@Override {
public void onNothingSelected(AdapterView<?> adapter) { mEncryptionAlgorithm.setValue(newValue.toString());
// nothing to do mEncryptionAlgorithm.setSummary(mEncryptionAlgorithm.getEntry());
mPreferences.setDefaultEncryptionAlgorithm(Integer.parseInt(newValue.toString()));
return false;
} }
}); });
mHashAlgorithm = (Spinner) findViewById(R.id.hashAlgorithm); mHashAlgorithm = (IntegerListPreference) findPreference(Constants.pref.default_hash_algorithm);
choices = new Choice[] { valueIds = new int[] {
new Choice(HashAlgorithmTags.MD5, "MD5"), HashAlgorithmTags.MD5, HashAlgorithmTags.RIPEMD160, HashAlgorithmTags.SHA1,
new Choice(HashAlgorithmTags.RIPEMD160, "RIPEMD160"), HashAlgorithmTags.SHA224, HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA384,
new Choice(HashAlgorithmTags.SHA1, "SHA1"), HashAlgorithmTags.SHA512,
new Choice(HashAlgorithmTags.SHA224, "SHA224"),
new Choice(HashAlgorithmTags.SHA256, "SHA256"),
new Choice(HashAlgorithmTags.SHA384, "SHA384"),
new Choice(HashAlgorithmTags.SHA512, "SHA512"),
}; };
adapter = new ArrayAdapter<Choice>(this, android.R.layout.simple_spinner_item, choices); entries = new String[] {
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); "MD5", "RIPEMD-160", "SHA-1",
mHashAlgorithm.setAdapter(adapter); "SHA-224", "SHA-256", "SHA-384",
"SHA-512",
int defaultHashAlgorithm = getDefaultHashAlgorithm(); };
for (int i = 0; i < choices.length; ++i) { values = new String[valueIds.length];
if (choices[i].getId() == defaultHashAlgorithm) { for (int i = 0; i < values.length; ++i) {
mHashAlgorithm.setSelection(i); values[i] = "" + valueIds[i];
break;
}
} }
mHashAlgorithm.setEntries(entries);
mHashAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() { mHashAlgorithm.setEntryValues(values);
@Override mHashAlgorithm.setValue("" + mPreferences.getDefaultHashAlgorithm());
public void onItemSelected(AdapterView<?> adapter, View view, int index, long id) { mHashAlgorithm.setSummary(mHashAlgorithm.getEntry());
setDefaultHashAlgorithm(((Choice) mHashAlgorithm.getSelectedItem()).getId()); mHashAlgorithm.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
} {
public boolean onPreferenceChange(Preference preference, Object newValue)
@Override {
public void onNothingSelected(AdapterView<?> adapter) { mHashAlgorithm.setValue(newValue.toString());
// nothing to do mHashAlgorithm.setSummary(mHashAlgorithm.getEntry());
mPreferences.setDefaultHashAlgorithm(Integer.parseInt(newValue.toString()));
return false;
} }
}); });
mMessageCompression = (Spinner) findViewById(R.id.messageCompression); mMessageCompression = (IntegerListPreference) findPreference(Constants.pref.default_message_compression);
choices = new Choice[] { valueIds = new int[] {
new Choice(Id.choice.compression.none, getString(R.string.choice_none)), Id.choice.compression.none, Id.choice.compression.zip,
new Choice(Id.choice.compression.zip, "ZIP"), Id.choice.compression.bzip2, Id.choice.compression.zlib,
new Choice(Id.choice.compression.bzip2, "BZIP2"),
new Choice(Id.choice.compression.zlib, "ZLIB"),
}; };
adapter = new ArrayAdapter<Choice>(this, android.R.layout.simple_spinner_item, choices); entries = new String[] {
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); getString(R.string.choice_none), "ZIP",
mMessageCompression.setAdapter(adapter); "BZIP2", "ZLIB",
};
int defaultMessageCompression = getDefaultMessageCompression(); values = new String[valueIds.length];
for (int i = 0; i < choices.length; ++i) { for (int i = 0; i < values.length; ++i) {
if (choices[i].getId() == defaultMessageCompression) { values[i] = "" + valueIds[i];
mMessageCompression.setSelection(i);
break;
}
} }
mMessageCompression.setEntries(entries);
mMessageCompression.setOnItemSelectedListener(new OnItemSelectedListener() { mMessageCompression.setEntryValues(values);
@Override mMessageCompression.setValue("" + mPreferences.getDefaultMessageCompression());
public void onItemSelected(AdapterView<?> adapter, View view, int index, long id) { mMessageCompression.setSummary(mMessageCompression.getEntry());
setDefaultMessageCompression(((Choice) mMessageCompression.getSelectedItem()).getId()); mMessageCompression.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
} {
public boolean onPreferenceChange(Preference preference, Object newValue)
@Override {
public void onNothingSelected(AdapterView<?> adapter) { mMessageCompression.setValue(newValue.toString());
// nothing to do mMessageCompression.setSummary(mMessageCompression.getEntry());
mPreferences.setDefaultMessageCompression(Integer.parseInt(newValue.toString()));
return false;
} }
}); });
mFileCompression = (Spinner) findViewById(R.id.fileCompression); mFileCompression = (IntegerListPreference) findPreference(Constants.pref.default_file_compression);
choices = new Choice[] { mFileCompression.setEntries(entries);
new Choice(Id.choice.compression.none, getString(R.string.choice_none)), mFileCompression.setEntryValues(values);
new Choice(Id.choice.compression.zip, "ZIP"), mFileCompression.setValue("" + mPreferences.getDefaultFileCompression());
new Choice(Id.choice.compression.bzip2, "BZIP2"), mFileCompression.setSummary(mFileCompression.getEntry());
new Choice(Id.choice.compression.zlib, "ZLIB"), mFileCompression.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
}; {
adapter = new ArrayAdapter<Choice>(this, android.R.layout.simple_spinner_item, choices); public boolean onPreferenceChange(Preference preference, Object newValue)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); {
mFileCompression.setAdapter(adapter); mFileCompression.setValue(newValue.toString());
mFileCompression.setSummary(mFileCompression.getEntry());
int defaultFileCompression = getDefaultFileCompression(); mPreferences.setDefaultFileCompression(Integer.parseInt(newValue.toString()));
for (int i = 0; i < choices.length; ++i) { return false;
if (choices[i].getId() == defaultFileCompression) {
mFileCompression.setSelection(i);
break;
}
}
mFileCompression.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapter, View view, int index, long id) {
setDefaultFileCompression(((Choice) mFileCompression.getSelectedItem()).getId());
}
@Override
public void onNothingSelected(AdapterView<?> adapter) {
// nothing to do
} }
}); });
mAsciiArmour = (CheckBox) findViewById(R.id.asciiArmour); mAsciiArmour = (CheckBoxPreference) findPreference(Constants.pref.default_ascii_armour);
mAsciiArmour.setChecked(getDefaultAsciiArmour()); mAsciiArmour.setChecked(mPreferences.getDefaultAsciiArmour());
mAsciiArmour.setOnClickListener(new OnClickListener() { mAsciiArmour.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
@Override {
public void onClick(View v) { public boolean onPreferenceChange(Preference preference, Object newValue)
setDefaultAsciiArmour(mAsciiArmour.isChecked()); {
mAsciiArmour.setChecked((Boolean)newValue);
mPreferences.setDefaultAsciiArmour((Boolean)newValue);
return false;
} }
}); });
} }