diff --git a/res/color/text_color_dark_theme.xml b/res/color/text_color_dark_theme.xml new file mode 100644 index 0000000000..95308fe1a5 --- /dev/null +++ b/res/color/text_color_dark_theme.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/res/color/text_color_light_theme.xml b/res/color/text_color_light_theme.xml new file mode 100644 index 0000000000..4bb2be8862 --- /dev/null +++ b/res/color/text_color_light_theme.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/res/color/text_color_secondary_dark_theme.xml b/res/color/text_color_secondary_dark_theme.xml new file mode 100644 index 0000000000..5510b324c7 --- /dev/null +++ b/res/color/text_color_secondary_dark_theme.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/res/color/text_color_secondary_light_theme.xml b/res/color/text_color_secondary_light_theme.xml new file mode 100644 index 0000000000..73eb8882ba --- /dev/null +++ b/res/color/text_color_secondary_light_theme.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/res/values/colors.xml b/res/values/colors.xml index 419ac55c30..bc847446a8 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -5,6 +5,9 @@ #ff000000 #ffeeeeee #ffdddddd + #ffababab + #ffbbbbbb + #ff808080 #ff111111 #7F111111 diff --git a/res/values/strings.xml b/res/values/strings.xml index 99f813f5d2..9c36f7e55b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8,7 +8,7 @@ Currently: %s You haven\'t set a passphrase yet! - messages per conversation + %s messages per conversation Delete all old messages now? Are you sure you would like to immediately trim all conversation threads to the %s most recent messages? Delete @@ -31,6 +31,15 @@ Touch to change your default SMS app Incoming SMS Disabled Touch to make TextSecure your default SMS app + on + On + off + Off + partial + SMS + MMS + Incoming SMS + outgoing SMS Can\'t find an app to select media. @@ -463,8 +472,10 @@ Import a plaintext backup file. Compatible with \'SMSBackup And Restore.\' - - Manual MMS settings are required for your phone. + + Manual MMS settings are required for your phone. + Enabled + Disabled Unlock @@ -583,6 +594,8 @@ My identity key + General + SMS and MMS Push and SMS Receive all SMS Receive all MMS @@ -599,8 +612,8 @@ Change passphrase Change my passphrase Complete key exchanges - Disable passphrase - Disable local encryption of messages and keys + Enable passphrase + Enable local encryption of messages and keys Screen security Automatically complete key exchanges for new sessions or for existing sessions with the same identity key Block screenshots in the recents list and inside the app @@ -612,6 +625,7 @@ Notifications Display message notifications in status bar LED color + Unknown LED blink pattern Set custom LED blink pattern On for: @@ -638,9 +652,9 @@ Slow Custom Advanced - Passphrase - MMS preferences - Enable manual MMS + App protection + Manual MMS settings + Use manual MMS settings Override system MMS settings with the information below. MMSC URL (Required) MMS Proxy Host (Optional) @@ -651,7 +665,6 @@ Request a delivery report for each SMS message you send Automatically delete older messages once a conversation thread exceeds a specified length Delete old messages - Storage Conversation length limit Trim all threads now Scan through all conversation threads and enforce conversation length limits diff --git a/res/values/themes.xml b/res/values/themes.xml index 8efd011101..4bb5713372 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -11,6 +11,8 @@ @drawable/actionbar_icon_holo_light @style/TextSecure.LightActionBar @style/TextSecure.LightActionBar + @color/text_color_light_theme + @color/text_color_secondary_light_theme @drawable/conversation_list_item_background_read_light @drawable/conversation_list_item_background_unread_light @drawable/list_selected_holo_light @@ -88,6 +90,8 @@ @style/TextSecure.DarkActionBar @style/TextSecure.DarkActionBar + @color/text_color_dark_theme + @color/text_color_secondary_dark_theme @drawable/conversation_list_item_background_read_dark @drawable/conversation_list_item_background_unread_dark @drawable/list_selected_holo_dark diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 692fdc32b2..c86197a658 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -1,177 +1,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:key="pref_toggle_push_messaging" + android:title="@string/preferences__use_data_channel" + android:summary="@string/preferences__use_the_data_channel_for_communication_with_other_textsecure_users"/> - + - - + - + - + - + - + diff --git a/res/xml/preferences_advanced.xml b/res/xml/preferences_advanced.xml new file mode 100644 index 0000000000..f324b05504 --- /dev/null +++ b/res/xml/preferences_advanced.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/res/xml/preferences_app_protection.xml b/res/xml/preferences_app_protection.xml new file mode 100644 index 0000000000..a527c98d65 --- /dev/null +++ b/res/xml/preferences_app_protection.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + diff --git a/res/xml/preferences_appearance.xml b/res/xml/preferences_appearance.xml new file mode 100644 index 0000000000..bcb237df5e --- /dev/null +++ b/res/xml/preferences_appearance.xml @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/res/xml/mms_preferences.xml b/res/xml/preferences_manual_mms.xml similarity index 100% rename from res/xml/mms_preferences.xml rename to res/xml/preferences_manual_mms.xml diff --git a/res/xml/preferences_notifications.xml b/res/xml/preferences_notifications.xml new file mode 100644 index 0000000000..842ff72a8e --- /dev/null +++ b/res/xml/preferences_notifications.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/xml/preferences_sms_mms.xml b/res/xml/preferences_sms_mms.xml new file mode 100644 index 0000000000..1f1b5be3c9 --- /dev/null +++ b/res/xml/preferences_sms_mms.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/xml/preferences_storage.xml b/res/xml/preferences_storage.xml new file mode 100644 index 0000000000..00cd1f5d01 --- /dev/null +++ b/res/xml/preferences_storage.xml @@ -0,0 +1,20 @@ + + + + + + + + + + diff --git a/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java b/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java index 1eaf897b8f..d7f348e6f9 100644 --- a/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java +++ b/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java @@ -16,55 +16,40 @@ */ package org.thoughtcrime.securesms; -import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; -import android.media.Ringtone; -import android.media.RingtoneManager; -import android.net.Uri; import android.os.AsyncTask; -import android.os.Build; import android.os.Bundle; import android.preference.CheckBoxPreference; -import android.preference.EditTextPreference; -import android.preference.ListPreference; import android.preference.Preference; -import android.preference.PreferenceGroup; -import android.preference.PreferenceManager; import android.preference.PreferenceScreen; -import android.preference.RingtonePreference; -import android.provider.ContactsContract; -import android.provider.Settings; -import android.provider.Telephony; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.preference.PreferenceFragment; -import android.text.TextUtils; import android.util.Log; -import android.view.MenuItem; import android.widget.Toast; import com.google.android.gms.gcm.GoogleCloudMessaging; -import org.thoughtcrime.securesms.components.OutgoingSmsPreference; -import org.thoughtcrime.securesms.contacts.ContactAccessor; -import org.thoughtcrime.securesms.contacts.ContactIdentityManager; import org.thoughtcrime.securesms.crypto.MasterSecret; -import org.thoughtcrime.securesms.crypto.MasterSecretUtil; +import org.thoughtcrime.securesms.preferences.AdvancedPreferenceFragment; +import org.thoughtcrime.securesms.preferences.AppProtectionPreferenceFragment; +import org.thoughtcrime.securesms.preferences.AppearancePreferenceFragment; +import org.thoughtcrime.securesms.preferences.NotificationsPreferenceFragment; +import org.thoughtcrime.securesms.preferences.SmsMmsPreferenceFragment; +import org.thoughtcrime.securesms.preferences.StoragePreferenceFragment; import org.thoughtcrime.securesms.push.TextSecureCommunicationFactory; -import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.util.Dialogs; import org.thoughtcrime.securesms.util.DynamicLanguage; import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.MemoryCleaner; +import org.thoughtcrime.securesms.util.ProgressDialogAsyncTask; import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.thoughtcrime.securesms.util.Trimmer; -import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libaxolotl.util.guava.Optional; import org.whispersystems.textsecure.api.TextSecureAccountManager; import org.whispersystems.textsecure.api.push.exceptions.AuthorizationFailedException; @@ -81,17 +66,16 @@ import java.io.IOException; public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarActivity implements SharedPreferences.OnSharedPreferenceChangeListener { - private static final String TAG = "Preferences"; + private static final String TAG = ApplicationPreferencesActivity.class.getSimpleName(); - private static final int PICK_IDENTITY_CONTACT = 1; - private static final int ENABLE_PASSPHRASE_ACTIVITY = 2; + private static final String PREFERENCE_CATEGORY_SMS_MMS = "preference_category_sms_mms"; + private static final String PREFERENCE_CATEGORY_NOTIFICATIONS = "preference_category_notifications"; + private static final String PREFERENCE_CATEGORY_APP_PROTECTION = "preference_category_app_protection"; + private static final String PREFERENCE_CATEGORY_APPEARANCE = "preference_category_appearance"; + private static final String PREFERENCE_CATEGORY_STORAGE = "preference_category_storage"; + private static final String PREFERENCE_CATEGORY_ADVANCED = "preference_category_advanced"; - private static final String DISPLAY_CATEGORY_PREF = "pref_display_category"; - private static final String PUSH_MESSAGING_PREF = "pref_toggle_push_messaging"; - private static final String MMS_PREF = "pref_mms_preferences"; - private static final String KITKAT_DEFAULT_PREF = "pref_set_default"; - private static final String SUBMIT_DEBUG_LOG_PREF = "pref_submit_debug_logs"; - private static final String OUTGOING_SMS_PREF = "pref_outgoing_sms"; + private static final String PUSH_MESSAGING_PREF = "pref_toggle_push_messaging"; private final DynamicTheme dynamicTheme = new DynamicTheme(); private final DynamicLanguage dynamicLanguage = new DynamicLanguage(); @@ -126,6 +110,20 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA fragment.onActivityResult(requestCode, resultCode, data); } + @Override + public boolean onSupportNavigateUp() { + FragmentManager fragmentManager = getSupportFragmentManager(); + if (fragmentManager.getBackStackEntryCount() > 0) { + fragmentManager.popBackStack(); + } else { + Intent intent = new Intent(this, ConversationListActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + finish(); + } + return true; + } + @Override public void onDestroy() { MemoryCleaner.clean((MasterSecret) getIntent().getParcelableExtra("master_secret")); @@ -141,491 +139,186 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA } } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - Intent intent = new Intent(this, ConversationListActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivity(intent); - finish(); - return true; - } - - return false; - } - public static class ApplicationPreferenceFragment extends PreferenceFragment { - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - addPreferencesFromResource(R.xml.preferences); - - initializeIdentitySelection(); - initializePushMessagingToggle(); - - this.findPreference(TextSecurePreferences.CHANGE_PASSPHRASE_PREF) - .setOnPreferenceClickListener(new ChangePassphraseClickListener()); - this.findPreference(TextSecurePreferences.THREAD_TRIM_NOW) - .setOnPreferenceClickListener(new TrimNowClickListener()); - this.findPreference(TextSecurePreferences.THREAD_TRIM_LENGTH) - .setOnPreferenceChangeListener(new TrimLengthValidationListener()); - this.findPreference(TextSecurePreferences.DISABLE_PASSPHRASE_PREF) - .setOnPreferenceChangeListener(new DisablePassphraseClickListener()); - this.findPreference(MMS_PREF) - .setOnPreferenceClickListener(new ApnPreferencesClickListener()); - this.findPreference(TextSecurePreferences.LED_COLOR_PREF) - .setOnPreferenceChangeListener(new ListSummaryListener()); - this.findPreference(TextSecurePreferences.LED_BLINK_PREF) - .setOnPreferenceChangeListener(new ListSummaryListener()); - this.findPreference(TextSecurePreferences.RINGTONE_PREF) - .setOnPreferenceChangeListener(new RingtoneSummaryListener()); - this.findPreference(SUBMIT_DEBUG_LOG_PREF) - .setOnPreferenceClickListener(new SubmitDebugLogListener()); - this.findPreference(OUTGOING_SMS_PREF) - .setOnPreferenceChangeListener(new OutgoingSmsPreferenceListener()); - - initializeOutgoingSmsSummary((OutgoingSmsPreference) findPreference(OUTGOING_SMS_PREF)); - initializeListSummary((ListPreference) findPreference(TextSecurePreferences.LED_COLOR_PREF)); - initializeListSummary((ListPreference) findPreference(TextSecurePreferences.LED_BLINK_PREF)); - initializeRingtoneSummary((RingtonePreference) findPreference(TextSecurePreferences.RINGTONE_PREF)); - } - - @Override - public void onStart() { - super.onStart(); - getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener((ApplicationPreferencesActivity)getActivity()); - } - - @Override - public void onResume() { - super.onResume(); - - initializePlatformSpecificOptions(); - } - - @Override - public void onStop() { - super.onStop(); - getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener((ApplicationPreferencesActivity)getActivity()); - } - - @Override - public void onActivityResult(int reqCode, int resultCode, Intent data) { - super.onActivityResult(reqCode, resultCode, data); - - Log.w("ApplicationPreferencesActivity", "Got result: " + resultCode + " for req: " + reqCode); - - if (resultCode == Activity.RESULT_OK) { - switch (reqCode) { - case PICK_IDENTITY_CONTACT: handleIdentitySelection(data); break; - case ENABLE_PASSPHRASE_ACTIVITY: getActivity().finish(); break; - } + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + addPreferencesFromResource(R.xml.preferences); + + initializePushMessagingToggle(); + + this.findPreference(PREFERENCE_CATEGORY_SMS_MMS) + .setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_SMS_MMS)); + this.findPreference(PREFERENCE_CATEGORY_NOTIFICATIONS) + .setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_NOTIFICATIONS)); + this.findPreference(PREFERENCE_CATEGORY_APP_PROTECTION) + .setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_APP_PROTECTION)); + this.findPreference(PREFERENCE_CATEGORY_APPEARANCE) + .setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_APPEARANCE)); + this.findPreference(PREFERENCE_CATEGORY_STORAGE) + .setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_STORAGE)); + this.findPreference(PREFERENCE_CATEGORY_ADVANCED) + .setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_ADVANCED)); } - } - private void initializePlatformSpecificOptions() { - PreferenceGroup pushSmsCategory = (PreferenceGroup) findPreference("push_sms_category"); - PreferenceGroup advancedCategory = (PreferenceGroup) findPreference("advanced_category"); - Preference defaultPreference = findPreference(KITKAT_DEFAULT_PREF); - Preference allSmsPreference = findPreference(TextSecurePreferences.ALL_SMS_PREF); - Preference allMmsPreference = findPreference(TextSecurePreferences.ALL_MMS_PREF); - Preference screenSecurityPreference = findPreference(TextSecurePreferences.SCREEN_SECURITY_PREF); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && pushSmsCategory != null) { - if (allSmsPreference != null) pushSmsCategory.removePreference(allSmsPreference); - if (allMmsPreference != null) pushSmsCategory.removePreference(allMmsPreference); - - if (Util.isDefaultSmsProvider(getActivity())) { - defaultPreference.setIntent(new Intent(Settings.ACTION_WIRELESS_SETTINGS)); - defaultPreference.setTitle(getString(R.string.ApplicationPreferencesActivity_sms_enabled)); - defaultPreference.setSummary(getString(R.string.ApplicationPreferencesActivity_touch_to_change_your_default_sms_app)); - } else { - Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT); - intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, getActivity().getPackageName()); - defaultPreference.setIntent(intent); - defaultPreference.setTitle(getString(R.string.ApplicationPreferencesActivity_sms_disabled)); - defaultPreference.setSummary(getString(R.string.ApplicationPreferencesActivity_touch_to_make_textsecure_your_default_sms_app)); - } - } else if (pushSmsCategory != null && defaultPreference != null) { - pushSmsCategory.removePreference(defaultPreference); + @Override + public void onResume() { + super.onResume(); + ((ApplicationPreferencesActivity) getActivity()).getSupportActionBar().setTitle(R.string.text_secure_normal__menu_settings); + setCategorySummaries(); } - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH && - advancedCategory != null && - screenSecurityPreference != null) - { - advancedCategory.removePreference(screenSecurityPreference); + private void setCategorySummaries() { + this.findPreference(PREFERENCE_CATEGORY_SMS_MMS) + .setSummary(SmsMmsPreferenceFragment.getSummary(getActivity())); + this.findPreference(PREFERENCE_CATEGORY_NOTIFICATIONS) + .setSummary(NotificationsPreferenceFragment.getSummary(getActivity())); + this.findPreference(PREFERENCE_CATEGORY_APP_PROTECTION) + .setSummary(AppProtectionPreferenceFragment.getSummary(getActivity())); + this.findPreference(PREFERENCE_CATEGORY_APPEARANCE) + .setSummary(AppearancePreferenceFragment.getSummary(getActivity())); + this.findPreference(PREFERENCE_CATEGORY_STORAGE) + .setSummary(StoragePreferenceFragment.getSummary(getActivity())); } - } - private void initializeEditTextSummary(final EditTextPreference preference) { - if (preference.getText() == null) { - preference.setSummary("Not set"); - } else { - preference.setSummary(preference.getText()); - } + private class CategoryClickListener implements Preference.OnPreferenceClickListener { + private String category; - preference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference pref, Object newValue) { - preference.setSummary(newValue == null ? "Not set" : ((String) newValue)); - return true; + public CategoryClickListener(String category) { + this.category = category; } - }); - } - private void initializePushMessagingToggle() { - CheckBoxPreference preference = (CheckBoxPreference)this.findPreference(PUSH_MESSAGING_PREF); - preference.setChecked(TextSecurePreferences.isPushRegistered(getActivity())); - preference.setOnPreferenceChangeListener(new PushMessagingClickListener()); - } + @Override + public boolean onPreferenceClick(Preference preference) { + Fragment fragment; - private void initializeIdentitySelection() { - ContactIdentityManager identity = ContactIdentityManager.getInstance(getActivity()); + switch (category) { + case PREFERENCE_CATEGORY_SMS_MMS: + fragment = new SmsMmsPreferenceFragment(); + break; + case PREFERENCE_CATEGORY_NOTIFICATIONS: + fragment = new NotificationsPreferenceFragment(); + break; + case PREFERENCE_CATEGORY_APP_PROTECTION: + fragment = new AppProtectionPreferenceFragment(); + break; + case PREFERENCE_CATEGORY_APPEARANCE: + fragment = new AppearancePreferenceFragment(); + break; + case PREFERENCE_CATEGORY_STORAGE: + fragment = new StoragePreferenceFragment(); + break; + case PREFERENCE_CATEGORY_ADVANCED: + fragment = new AdvancedPreferenceFragment(); + break; + default: + throw new AssertionError(); + } - if (identity.isSelfIdentityAutoDetected()) { - Preference preference = this.findPreference(DISPLAY_CATEGORY_PREF); - this.getPreferenceScreen().removePreference(preference); - } else { - Uri contactUri = identity.getSelfIdentityUri(); + FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + fragmentTransaction.replace(android.R.id.content, fragment); + fragmentTransaction.addToBackStack(null); + fragmentTransaction.commit(); - if (contactUri != null) { - String contactName = ContactAccessor.getInstance().getNameFromContact(getActivity(), contactUri); - this.findPreference(TextSecurePreferences.IDENTITY_PREF) - .setSummary(String.format(getString(R.string.ApplicationPreferencesActivity_currently_s), - contactName)); + return true; } - - this.findPreference(TextSecurePreferences.IDENTITY_PREF) - .setOnPreferenceClickListener(new IdentityPreferenceClickListener()); } - } - - private void initializeListSummary(ListPreference pref) { - pref.setSummary(pref.getEntry()); - } - private void initializeRingtoneSummary(RingtonePreference pref) { - RingtoneSummaryListener listener = - (RingtoneSummaryListener) pref.getOnPreferenceChangeListener(); - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); - - listener.onPreferenceChange(pref, sharedPreferences.getString(pref.getKey(), "")); - } - - private void initializeOutgoingSmsSummary(OutgoingSmsPreference pref) { - pref.setSummary(buildOutgoingSmsDescription()); - } - - private void handleIdentitySelection(Intent data) { - Uri contactUri = data.getData(); - - if (contactUri != null) { - TextSecurePreferences.setIdentityContactUri(getActivity(), contactUri.toString()); - initializeIdentitySelection(); + private void initializePushMessagingToggle() { + CheckBoxPreference preference = (CheckBoxPreference)this.findPreference(PUSH_MESSAGING_PREF); + preference.setChecked(TextSecurePreferences.isPushRegistered(getActivity())); + preference.setOnPreferenceChangeListener(new PushMessagingClickListener()); } - } - - private class PushMessagingClickListener implements Preference.OnPreferenceChangeListener { - - private static final int SUCCESS = 0; - private static final int NETWORK_ERROR = 1; - private class DisablePushMessagesTask extends AsyncTask { - private ProgressDialog dialog; - private final Preference preference; - - public DisablePushMessagesTask(final Preference preference) { - this.preference = preference; - } + private class PushMessagingClickListener implements Preference.OnPreferenceChangeListener { + private static final int SUCCESS = 0; + private static final int NETWORK_ERROR = 1; - @Override - protected void onPreExecute() { - dialog = ProgressDialog.show(getActivity(), - getString(R.string.ApplicationPreferencesActivity_unregistering), - getString(R.string.ApplicationPreferencesActivity_unregistering_for_data_based_communication), - true, false); - } + private class DisablePushMessagesTask extends ProgressDialogAsyncTask { + private final CheckBoxPreference checkBoxPreference; - @Override - protected void onPostExecute(Integer result) { - if (dialog != null) - dialog.dismiss(); + public DisablePushMessagesTask(final CheckBoxPreference checkBoxPreference) { + super(getActivity(), R.string.ApplicationPreferencesActivity_unregistering, R.string.ApplicationPreferencesActivity_unregistering_for_data_based_communication); + this.checkBoxPreference = checkBoxPreference; + } - switch (result) { + @Override + protected void onPostExecute(Integer result) { + super.onPostExecute(result); + switch (result) { case NETWORK_ERROR: Toast.makeText(getActivity(), - getString(R.string.ApplicationPreferencesActivity_error_connecting_to_server), + R.string.ApplicationPreferencesActivity_error_connecting_to_server, Toast.LENGTH_LONG).show(); break; case SUCCESS: - ((CheckBoxPreference)preference).setChecked(false); + checkBoxPreference.setChecked(false); TextSecurePreferences.setPushRegistered(getActivity(), false); break; - } - } - - @Override - protected Integer doInBackground(Void... params) { - try { - Context context = getActivity(); - TextSecureAccountManager accountManager = TextSecureCommunicationFactory.createManager(context); - - accountManager.setGcmId(Optional.absent()); - GoogleCloudMessaging.getInstance(context).unregister(); - - return SUCCESS; - } catch (AuthorizationFailedException afe) { - Log.w("ApplicationPreferencesActivity", afe); - return SUCCESS; - } catch (IOException ioe) { - Log.w("ApplicationPreferencesActivity", ioe); - return NETWORK_ERROR; - } - } - } - - @Override - public boolean onPreferenceChange(final Preference preference, Object newValue) { - if (((CheckBoxPreference)preference).isChecked()) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setIcon(Dialogs.resolveIcon(getActivity(), R.attr.dialog_info_icon)); - builder.setTitle(getString(R.string.ApplicationPreferencesActivity_disable_push_messages)); - builder.setMessage(getString(R.string.ApplicationPreferencesActivity_this_will_disable_push_messages)); - builder.setNegativeButton(android.R.string.cancel, null); - builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - new DisablePushMessagesTask(preference).execute(); } - }); - builder.show(); - } else { - Intent intent = new Intent(getActivity(), RegistrationActivity.class); - intent.putExtra("master_secret", getActivity().getIntent().getParcelableExtra("master_secret")); - startActivity(intent); - } - - return false; - } - } - - private class IdentityPreferenceClickListener implements Preference.OnPreferenceClickListener { - @Override - public boolean onPreferenceClick(Preference preference) { - Intent intent = new Intent(Intent.ACTION_PICK); - intent.setType(ContactsContract.Contacts.CONTENT_TYPE); - startActivityForResult(intent, PICK_IDENTITY_CONTACT); - return true; - } - } - - - private class ChangePassphraseClickListener implements Preference.OnPreferenceClickListener { - @Override - public boolean onPreferenceClick(Preference preference) { - if (MasterSecretUtil.isPassphraseInitialized(getActivity())) { - startActivity(new Intent(getActivity(), PassphraseChangeActivity.class)); - } else { - Toast.makeText(getActivity(), - R.string.ApplicationPreferenceActivity_you_havent_set_a_passphrase_yet, - Toast.LENGTH_LONG).show(); - } - - return true; - } - } - - private class TrimNowClickListener implements Preference.OnPreferenceClickListener { - @Override - public boolean onPreferenceClick(Preference preference) { - final int threadLengthLimit = TextSecurePreferences.getThreadTrimLength(getActivity()); - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle(R.string.ApplicationPreferencesActivity_delete_all_old_messages_now); - builder.setMessage(String.format(getString(R.string.ApplicationPreferencesActivity_are_you_sure_you_would_like_to_immediately_trim_all_conversation_threads_to_the_s_most_recent_messages), - threadLengthLimit)); - builder.setPositiveButton(R.string.ApplicationPreferencesActivity_delete, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Trimmer.trimAllThreads(getActivity(), threadLengthLimit); } - }); - builder.setNegativeButton(android.R.string.cancel, null); - builder.show(); - - return true; - } - } - - private class DisablePassphraseClickListener implements Preference.OnPreferenceChangeListener { - - @Override - public boolean onPreferenceChange(final Preference preference, Object newValue) { - if (!((CheckBoxPreference)preference).isChecked()) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle(R.string.ApplicationPreferencesActivity_disable_storage_encryption); - builder.setMessage(R.string.ApplicationPreferencesActivity_warning_this_will_disable_storage_encryption_for_all_messages); - builder.setIcon(Dialogs.resolveIcon(getActivity(), R.attr.dialog_alert_icon)); - builder.setPositiveButton(R.string.ApplicationPreferencesActivity_disable, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - MasterSecret masterSecret = getActivity().getIntent().getParcelableExtra("master_secret"); - MasterSecretUtil.changeMasterSecretPassphrase(getActivity(), - masterSecret, - MasterSecretUtil.UNENCRYPTED_PASSPHRASE); - - - TextSecurePreferences.setPasswordDisabled(getActivity(), true); - ((CheckBoxPreference)preference).setChecked(true); - - Intent intent = new Intent(getActivity(), KeyCachingService.class); - intent.setAction(KeyCachingService.DISABLE_ACTION); - getActivity().startService(intent); + @Override + protected Integer doInBackground(Void... params) { + try { + Context context = getActivity(); + TextSecureAccountManager accountManager = TextSecureCommunicationFactory.createManager(context); + + accountManager.setGcmId(Optional.absent()); + GoogleCloudMessaging.getInstance(context).unregister(); + + return SUCCESS; + } catch (AuthorizationFailedException afe) { + Log.w(TAG, afe); + return SUCCESS; + } catch (IOException ioe) { + Log.w(TAG, ioe); + return NETWORK_ERROR; } - }); - builder.setNegativeButton(android.R.string.cancel, null); - builder.show(); - } else { - Intent intent = new Intent(getActivity(), - PassphraseChangeActivity.class); - startActivityForResult(intent, ENABLE_PASSPHRASE_ACTIVITY); - } - - return false; - } - } - - private class TrimLengthValidationListener implements Preference.OnPreferenceChangeListener { - - public TrimLengthValidationListener() { - EditTextPreference preference = (EditTextPreference)findPreference(TextSecurePreferences.THREAD_TRIM_LENGTH); - preference.setSummary(preference.getText() + " " + getString(R.string.ApplicationPreferencesActivity_messages_per_conversation)); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (newValue == null || ((String)newValue).trim().length() == 0) { - return false; - } - - try { - Integer.parseInt((String)newValue); - } catch (NumberFormatException nfe) { - Log.w("ApplicationPreferencesActivity", nfe); - return false; - } - - if (Integer.parseInt((String)newValue) < 1) { - return false; - } - - preference.setSummary(newValue + " " + - getString(R.string.ApplicationPreferencesActivity_messages_per_conversation)); - return true; - } - - } - - private class ApnPreferencesClickListener implements Preference.OnPreferenceClickListener { - - @Override - public boolean onPreferenceClick(Preference preference) { - startActivity(new Intent(getActivity(), MmsPreferencesActivity.class)); - return true; - } - } - - private class ListSummaryListener implements Preference.OnPreferenceChangeListener { - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - ListPreference asList = (ListPreference) preference; - - int index = 0; - for (; index < asList.getEntryValues().length; index++) { - if (value.equals(asList.getEntryValues()[index])) { - break; } } - asList.setSummary(asList.getEntries()[index]); - return true; - } - } - - private class RingtoneSummaryListener implements Preference.OnPreferenceChangeListener { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - String value = (String) newValue; - - if (TextUtils.isEmpty(value)) { - preference.setSummary(R.string.preferences__default); - } else { - Ringtone tone = RingtoneManager.getRingtone(getActivity(), - Uri.parse(value)); - if (tone != null) { - preference.setSummary(tone.getTitle(getActivity())); + @Override + public boolean onPreferenceChange(final Preference preference, Object newValue) { + if (((CheckBoxPreference)preference).isChecked()) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setIcon(Dialogs.resolveIcon(getActivity(), R.attr.dialog_info_icon)); + builder.setTitle(R.string.ApplicationPreferencesActivity_disable_push_messages); + builder.setMessage(R.string.ApplicationPreferencesActivity_this_will_disable_push_messages); + builder.setNegativeButton(android.R.string.cancel, null); + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + new DisablePushMessagesTask((CheckBoxPreference)preference).execute(); + } + }); + builder.show(); + } else { + Intent nextIntent = new Intent(getActivity(), ApplicationPreferencesActivity.class); + nextIntent.putExtra("master_secret", getActivity().getIntent().getParcelableExtra("master_secret")); + + Intent intent = new Intent(getActivity(), RegistrationActivity.class); + intent.putExtra("cancel_button", true); + intent.putExtra("next_intent", nextIntent); + intent.putExtra("master_secret", getActivity().getIntent().getParcelableExtra("master_secret")); + startActivity(intent); } - } - return true; - } - } - - private class SubmitDebugLogListener implements Preference.OnPreferenceClickListener { - @Override - public boolean onPreferenceClick(Preference preference) { - final Intent intent = new Intent(getActivity(), LogSubmitActivity.class); - startActivity(intent); - return true; + return false; + } } - } - - private class OutgoingSmsPreferenceListener implements Preference.OnPreferenceChangeListener { + /* http://code.google.com/p/android/issues/detail?id=4611#c35 */ + @SuppressWarnings("deprecation") @Override - public boolean onPreferenceChange(final Preference preference, Object newValue) { - - preference.setSummary(buildOutgoingSmsDescription()); + public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) + { + super.onPreferenceTreeClick(preferenceScreen, preference); + if (preference != null && preference instanceof PreferenceScreen && ((PreferenceScreen)preference).getDialog() != null) + ((PreferenceScreen) preference).getDialog().getWindow().getDecorView().setBackgroundDrawable(getActivity().getWindow().getDecorView().getBackground().getConstantState().newDrawable()); return false; } } - - private String buildOutgoingSmsDescription() { - final StringBuilder builder = new StringBuilder(); - final boolean dataFallback = TextSecurePreferences.isFallbackSmsAllowed(getActivity()); - final boolean dataFallbackAsk = TextSecurePreferences.isFallbackSmsAskRequired(getActivity()); - final boolean nonData = TextSecurePreferences.isDirectSmsAllowed(getActivity()); - - if (dataFallback) { - builder.append(getString(R.string.preferences__sms_outgoing_push_users)); - if (dataFallbackAsk) builder.append(" ").append(getString(R.string.preferences__sms_fallback_push_users_ask)); - } - if (nonData) { - if (dataFallback) builder.append(", "); - builder.append(getString(R.string.preferences__sms_fallback_non_push_users)); - } - if (!dataFallback && !nonData) { - builder.append(getString(R.string.preferences__sms_fallback_nobody)); - } - return builder.toString(); - } - - /* http://code.google.com/p/android/issues/detail?id=4611#c35 */ - @SuppressWarnings("deprecation") - @Override - public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) - { - super.onPreferenceTreeClick(preferenceScreen, preference); - if (preference!=null) - if (preference instanceof PreferenceScreen) - if (((PreferenceScreen)preference).getDialog()!=null) - ((PreferenceScreen)preference).getDialog().getWindow().getDecorView().setBackgroundDrawable(getActivity().getWindow().getDecorView().getBackground().getConstantState().newDrawable()); - return false; - } - } } diff --git a/src/org/thoughtcrime/securesms/MmsPreferencesFragment.java b/src/org/thoughtcrime/securesms/MmsPreferencesFragment.java index 5ccdb6cf8a..489d273ea9 100644 --- a/src/org/thoughtcrime/securesms/MmsPreferencesFragment.java +++ b/src/org/thoughtcrime/securesms/MmsPreferencesFragment.java @@ -16,6 +16,7 @@ */ package org.thoughtcrime.securesms; +import android.content.Context; import android.os.Bundle; import android.preference.EditTextPreference; import android.preference.Preference; @@ -33,15 +34,18 @@ public class MmsPreferencesFragment extends PreferenceFragment { super.onCreate(paramBundle); initializePreferences(); initializeEditTextSummaries(); + ((PassphraseRequiredActionBarActivity) getActivity()).getSupportActionBar() + .setTitle(R.string.preferences__advanced_mms_access_point_names); } private void initializePreferences() { if (!OutgoingMmsConnection.isConnectionPossible(getActivity())) { TextSecurePreferences.setUseLocalApnsEnabled(getActivity(), true); - addPreferencesFromResource(R.xml.mms_preferences); - this.findPreference(TextSecurePreferences.ENABLE_MANUAL_MMS_PREF).setOnPreferenceChangeListener(new OverrideMmsChangeListener()); + addPreferencesFromResource(R.xml.preferences_manual_mms); + this.findPreference(TextSecurePreferences.ENABLE_MANUAL_MMS_PREF) + .setOnPreferenceChangeListener(new OverrideMmsChangeListener()); } else { - addPreferencesFromResource(R.xml.mms_preferences); + addPreferencesFromResource(R.xml.preferences_manual_mms); } } @@ -73,8 +77,16 @@ public class MmsPreferencesFragment extends PreferenceFragment { @Override public boolean onPreferenceChange(Preference preference, Object o) { TextSecurePreferences.setUseLocalApnsEnabled(getActivity(), true); - Toast.makeText(getActivity(), R.string.mms_preferences_activity__manual_mms_settings_are_required, Toast.LENGTH_SHORT).show(); + Toast.makeText(getActivity(), R.string.MmsPreferencesFragment__manual_mms_settings_are_required, + Toast.LENGTH_SHORT).show(); return false; } } + + public static CharSequence getSummary(Context context) { + final int enabledResId = R.string.MmsPreferencesFragment__enabled; + final int disabledResId = R.string.MmsPreferencesFragment__disabled; + + return context.getString(TextSecurePreferences.isUseLocalApnsEnabled(context) ? enabledResId : disabledResId); + } } diff --git a/src/org/thoughtcrime/securesms/RegistrationActivity.java b/src/org/thoughtcrime/securesms/RegistrationActivity.java index 60befbabbe..b68d3d65bd 100644 --- a/src/org/thoughtcrime/securesms/RegistrationActivity.java +++ b/src/org/thoughtcrime/securesms/RegistrationActivity.java @@ -86,6 +86,10 @@ public class RegistrationActivity extends ActionBarActivity { this.number.addTextChangedListener(new NumberChangedListener()); this.createButton.setOnClickListener(new CreateButtonListener()); this.skipButton.setOnClickListener(new CancelButtonListener()); + + if (getIntent().getBooleanExtra("cancel_button", false)) { + this.skipButton.setText(android.R.string.cancel); + } } private void initializeSpinner() { diff --git a/src/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java b/src/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java new file mode 100644 index 0000000000..72e84ef8b7 --- /dev/null +++ b/src/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java @@ -0,0 +1,100 @@ +package org.thoughtcrime.securesms.preferences; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.preference.Preference; +import android.provider.ContactsContract; +import android.support.v4.preference.PreferenceFragment; +import android.util.Log; + +import org.thoughtcrime.securesms.ApplicationPreferencesActivity; +import org.thoughtcrime.securesms.LogSubmitActivity; +import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.contacts.ContactAccessor; +import org.thoughtcrime.securesms.contacts.ContactIdentityManager; +import org.thoughtcrime.securesms.util.TextSecurePreferences; + +public class AdvancedPreferenceFragment extends PreferenceFragment { + private static final String TAG = AdvancedPreferenceFragment.class.getSimpleName(); + + private static final String SUBMIT_DEBUG_LOG_PREF = "pref_submit_debug_logs"; + + private static final int PICK_IDENTITY_CONTACT = 1; + + @Override + public void onCreate(Bundle paramBundle) { + super.onCreate(paramBundle); + addPreferencesFromResource(R.xml.preferences_advanced); + + initializeIdentitySelection(); + + this.findPreference(SUBMIT_DEBUG_LOG_PREF) + .setOnPreferenceClickListener(new SubmitDebugLogListener()); + } + + @Override + public void onResume() { + super.onResume(); + ((ApplicationPreferencesActivity) getActivity()).getSupportActionBar().setTitle(R.string.preferences__advanced); + } + + @Override + public void onActivityResult(int reqCode, int resultCode, Intent data) { + super.onActivityResult(reqCode, resultCode, data); + + Log.w(TAG, "Got result: " + resultCode + " for req: " + reqCode); + if (resultCode == Activity.RESULT_OK && reqCode == PICK_IDENTITY_CONTACT) { + handleIdentitySelection(data); + } + } + + private void initializeIdentitySelection() { + ContactIdentityManager identity = ContactIdentityManager.getInstance(getActivity()); + + Preference preference = this.findPreference(TextSecurePreferences.IDENTITY_PREF); + + if (identity.isSelfIdentityAutoDetected()) { + this.getPreferenceScreen().removePreference(preference); + } else { + Uri contactUri = identity.getSelfIdentityUri(); + + if (contactUri != null) { + String contactName = ContactAccessor.getInstance().getNameFromContact(getActivity(), contactUri); + preference.setSummary(String.format(getString(R.string.ApplicationPreferencesActivity_currently_s), + contactName)); + } + + preference.setOnPreferenceClickListener(new IdentityPreferenceClickListener()); + } + } + + private class IdentityPreferenceClickListener implements Preference.OnPreferenceClickListener { + @Override + public boolean onPreferenceClick(Preference preference) { + Intent intent = new Intent(Intent.ACTION_PICK); + intent.setType(ContactsContract.Contacts.CONTENT_TYPE); + startActivityForResult(intent, PICK_IDENTITY_CONTACT); + return true; + } + } + + private void handleIdentitySelection(Intent data) { + Uri contactUri = data.getData(); + + if (contactUri != null) { + TextSecurePreferences.setIdentityContactUri(getActivity(), contactUri.toString()); + initializeIdentitySelection(); + } + } + + private class SubmitDebugLogListener implements Preference.OnPreferenceClickListener { + @Override + public boolean onPreferenceClick(Preference preference) { + final Intent intent = new Intent(getActivity(), LogSubmitActivity.class); + startActivity(intent); + return true; + } + } +} diff --git a/src/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java b/src/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java new file mode 100644 index 0000000000..776e7f85a5 --- /dev/null +++ b/src/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java @@ -0,0 +1,117 @@ +package org.thoughtcrime.securesms.preferences; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.Preference; +import android.preference.PreferenceScreen; +import android.support.v4.preference.PreferenceFragment; +import android.widget.Toast; + +import org.thoughtcrime.securesms.ApplicationPreferencesActivity; +import org.thoughtcrime.securesms.PassphraseChangeActivity; +import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.crypto.MasterSecret; +import org.thoughtcrime.securesms.crypto.MasterSecretUtil; +import org.thoughtcrime.securesms.service.KeyCachingService; +import org.thoughtcrime.securesms.util.Dialogs; +import org.thoughtcrime.securesms.util.TextSecurePreferences; + +public class AppProtectionPreferenceFragment extends PreferenceFragment { + private CheckBoxPreference disablePassphrase; + + @Override + public void onCreate(Bundle paramBundle) { + super.onCreate(paramBundle); + addPreferencesFromResource(R.xml.preferences_app_protection); + + disablePassphrase = (CheckBoxPreference) this.findPreference("pref_enable_passphrase_temporary"); + + this.findPreference(TextSecurePreferences.CHANGE_PASSPHRASE_PREF) + .setOnPreferenceClickListener(new ChangePassphraseClickListener()); + disablePassphrase + .setOnPreferenceChangeListener(new DisablePassphraseClickListener()); + } + + @Override + public void onResume() { + super.onResume(); + ((ApplicationPreferencesActivity) getActivity()).getSupportActionBar().setTitle(R.string.preferences__app_protection); + initializePlatformSpecificOptions(); + + disablePassphrase.setChecked(!TextSecurePreferences.isPasswordDisabled(getActivity())); + } + + private void initializePlatformSpecificOptions() { + PreferenceScreen preferenceScreen = getPreferenceScreen(); + Preference screenSecurityPreference = findPreference(TextSecurePreferences.SCREEN_SECURITY_PREF); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH && + screenSecurityPreference != null) { + preferenceScreen.removePreference(screenSecurityPreference); + } + } + + private class ChangePassphraseClickListener implements Preference.OnPreferenceClickListener { + @Override + public boolean onPreferenceClick(Preference preference) { + if (MasterSecretUtil.isPassphraseInitialized(getActivity())) { + startActivity(new Intent(getActivity(), PassphraseChangeActivity.class)); + } else { + Toast.makeText(getActivity(), + R.string.ApplicationPreferenceActivity_you_havent_set_a_passphrase_yet, + Toast.LENGTH_LONG).show(); + } + + return true; + } + } + + private class DisablePassphraseClickListener implements Preference.OnPreferenceChangeListener { + + @Override + public boolean onPreferenceChange(final Preference preference, Object newValue) { + if (((CheckBoxPreference)preference).isChecked()) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.ApplicationPreferencesActivity_disable_storage_encryption); + builder.setMessage(R.string.ApplicationPreferencesActivity_warning_this_will_disable_storage_encryption_for_all_messages); + builder.setIcon(Dialogs.resolveIcon(getActivity(), R.attr.dialog_alert_icon)); + builder.setPositiveButton(R.string.ApplicationPreferencesActivity_disable, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + MasterSecret masterSecret = getActivity().getIntent().getParcelableExtra("master_secret"); + MasterSecretUtil.changeMasterSecretPassphrase(getActivity(), + masterSecret, + MasterSecretUtil.UNENCRYPTED_PASSPHRASE); + + + TextSecurePreferences.setPasswordDisabled(getActivity(), true); + ((CheckBoxPreference)preference).setChecked(false); + + Intent intent = new Intent(getActivity(), KeyCachingService.class); + intent.setAction(KeyCachingService.DISABLE_ACTION); + getActivity().startService(intent); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + } else { + Intent intent = new Intent(getActivity(), PassphraseChangeActivity.class); + startActivity(intent); + } + + return false; + } + } + + public static CharSequence getSummary(Context context) { + final int onCapsResId = R.string.ApplicationPreferencesActivity_On; + final int offCapsResId = R.string.ApplicationPreferencesActivity_Off; + + return context.getString(TextSecurePreferences.isPasswordDisabled(context) ? offCapsResId : onCapsResId); + } +} diff --git a/src/org/thoughtcrime/securesms/preferences/AppearancePreferenceFragment.java b/src/org/thoughtcrime/securesms/preferences/AppearancePreferenceFragment.java new file mode 100644 index 0000000000..052a861548 --- /dev/null +++ b/src/org/thoughtcrime/securesms/preferences/AppearancePreferenceFragment.java @@ -0,0 +1,61 @@ +package org.thoughtcrime.securesms.preferences; + +import android.content.Context; +import android.os.Bundle; +import android.support.v4.preference.PreferenceFragment; + +import org.thoughtcrime.securesms.ApplicationPreferencesActivity; +import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.util.TextSecurePreferences; + +public class AppearancePreferenceFragment extends PreferenceFragment { + + @Override + public void onCreate(Bundle paramBundle) { + super.onCreate(paramBundle); + addPreferencesFromResource(R.xml.preferences_appearance); + } + + @Override + public void onStart() { + super.onStart(); + getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener((ApplicationPreferencesActivity)getActivity()); + } + + @Override + public void onResume() { + super.onResume(); + ((ApplicationPreferencesActivity) getActivity()).getSupportActionBar().setTitle(R.string.preferences__appearance); + } + + @Override + public void onStop() { + super.onStop(); + getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener((ApplicationPreferencesActivity) getActivity()); + } + + public static CharSequence getSummary(Context context) { + String[] languageEntries = context.getResources().getStringArray(R.array.language_entries); + String[] languageEntryValues = context.getResources().getStringArray(R.array.language_values); + String[] themeEntries = context.getResources().getStringArray(R.array.pref_theme_entries); + String[] themeEntryValues = context.getResources().getStringArray(R.array.pref_theme_values); + + Integer langIndex = findIndexOfValue(TextSecurePreferences.getLanguage(context), languageEntryValues); + Integer themeIndex = findIndexOfValue(TextSecurePreferences.getTheme(context), themeEntryValues); + + return context.getString(R.string.preferences__theme) + ": " + themeEntries[themeIndex] + ", " + + context.getString(R.string.preferences__language) + ": " + languageEntries[langIndex]; + } + + // Copy from ListPreference + private static int findIndexOfValue(String value, CharSequence[] mEntryValues) { + if (value != null && mEntryValues != null) { + for (int i = mEntryValues.length - 1; i >= 0; i--) { + if (mEntryValues[i].equals(value)) { + return i; + } + } + } + return -1; + } +} diff --git a/src/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.java b/src/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.java new file mode 100644 index 0000000000..dc4b6b67e5 --- /dev/null +++ b/src/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.java @@ -0,0 +1,97 @@ +package org.thoughtcrime.securesms.preferences; + +import android.content.Context; +import android.content.SharedPreferences; +import android.media.Ringtone; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.PreferenceManager; +import android.preference.RingtonePreference; +import android.support.v4.preference.PreferenceFragment; +import android.text.TextUtils; +import android.util.Log; + +import org.thoughtcrime.securesms.ApplicationPreferencesActivity; +import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.util.TextSecurePreferences; + +import java.util.Arrays; + +public class NotificationsPreferenceFragment extends PreferenceFragment { + + @Override + public void onCreate(Bundle paramBundle) { + super.onCreate(paramBundle); + addPreferencesFromResource(R.xml.preferences_notifications); + + this.findPreference(TextSecurePreferences.LED_COLOR_PREF) + .setOnPreferenceChangeListener(new ListSummaryListener()); + this.findPreference(TextSecurePreferences.LED_BLINK_PREF) + .setOnPreferenceChangeListener(new ListSummaryListener()); + this.findPreference(TextSecurePreferences.RINGTONE_PREF) + .setOnPreferenceChangeListener(new RingtoneSummaryListener()); + + initializeListSummary((ListPreference) findPreference(TextSecurePreferences.LED_COLOR_PREF)); + initializeListSummary((ListPreference) findPreference(TextSecurePreferences.LED_BLINK_PREF)); + initializeRingtoneSummary((RingtonePreference) findPreference(TextSecurePreferences.RINGTONE_PREF)); + } + + @Override + public void onResume() { + super.onResume(); + ((ApplicationPreferencesActivity) getActivity()).getSupportActionBar().setTitle(R.string.preferences__notifications); + } + + private class ListSummaryListener implements Preference.OnPreferenceChangeListener { + @Override + public boolean onPreferenceChange(Preference preference, Object value) { + ListPreference listPref = (ListPreference) preference; + + final int entryIndex = Arrays.asList(listPref.getEntryValues()).indexOf(value); + listPref.setSummary(entryIndex >= 0 && entryIndex < listPref.getEntries().length + ? listPref.getEntries()[entryIndex] + : getString(R.string.preferences__led_color_unknown)); + return true; + } + } + + private class RingtoneSummaryListener implements Preference.OnPreferenceChangeListener { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + String value = (String) newValue; + + if (TextUtils.isEmpty(value)) { + preference.setSummary(R.string.preferences__default); + } else { + Ringtone tone = RingtoneManager.getRingtone(getActivity(), Uri.parse(value)); + if (tone != null) { + preference.setSummary(tone.getTitle(getActivity())); + } + } + + return true; + } + } + + private void initializeListSummary(ListPreference pref) { + pref.setSummary(pref.getEntry()); + } + + private void initializeRingtoneSummary(RingtonePreference pref) { + RingtoneSummaryListener listener = + (RingtoneSummaryListener) pref.getOnPreferenceChangeListener(); + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); + + listener.onPreferenceChange(pref, sharedPreferences.getString(pref.getKey(), "")); + } + + public static CharSequence getSummary(Context context) { + final int onCapsResId = R.string.ApplicationPreferencesActivity_On; + final int offCapsResId = R.string.ApplicationPreferencesActivity_Off; + + return context.getString(TextSecurePreferences.isNotificationsEnabled(context) ? onCapsResId : offCapsResId); + } +} diff --git a/src/org/thoughtcrime/securesms/preferences/SmsMmsPreferenceFragment.java b/src/org/thoughtcrime/securesms/preferences/SmsMmsPreferenceFragment.java new file mode 100644 index 0000000000..36dc032916 --- /dev/null +++ b/src/org/thoughtcrime/securesms/preferences/SmsMmsPreferenceFragment.java @@ -0,0 +1,169 @@ +package org.thoughtcrime.securesms.preferences; + +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.PreferenceScreen; +import android.provider.Settings; +import android.provider.Telephony; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentTransaction; +import android.support.v4.preference.PreferenceFragment; + +import org.thoughtcrime.securesms.ApplicationPreferencesActivity; +import org.thoughtcrime.securesms.MmsPreferencesFragment; +import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.components.OutgoingSmsPreference; +import org.thoughtcrime.securesms.util.TextSecurePreferences; +import org.thoughtcrime.securesms.util.Util; + +public class SmsMmsPreferenceFragment extends PreferenceFragment { + private static final String KITKAT_DEFAULT_PREF = "pref_set_default"; + private static final String OUTGOING_SMS_PREF = "pref_outgoing_sms"; + private static final String MMS_PREF = "pref_mms_preferences"; + + @Override + public void onCreate(Bundle paramBundle) { + super.onCreate(paramBundle); + addPreferencesFromResource(R.xml.preferences_sms_mms); + + this.findPreference(OUTGOING_SMS_PREF) + .setOnPreferenceChangeListener(new OutgoingSmsPreferenceListener()); + this.findPreference(MMS_PREF) + .setOnPreferenceClickListener(new ApnPreferencesClickListener()); + + initializeOutgoingSmsSummary((OutgoingSmsPreference) findPreference(OUTGOING_SMS_PREF)); + } + + @Override + public void onResume() { + super.onResume(); + ((ApplicationPreferencesActivity) getActivity()).getSupportActionBar().setTitle(R.string.preferences__sms_mms); + this.findPreference(MMS_PREF) + .setSummary(MmsPreferencesFragment.getSummary(getActivity())); + + initializePlatformSpecificOptions(); + } + + private void initializePlatformSpecificOptions() { + PreferenceScreen preferenceScreen = getPreferenceScreen(); + Preference defaultPreference = findPreference(KITKAT_DEFAULT_PREF); + Preference allSmsPreference = findPreference(TextSecurePreferences.ALL_SMS_PREF); + Preference allMmsPreference = findPreference(TextSecurePreferences.ALL_MMS_PREF); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ) { + if (allSmsPreference != null) preferenceScreen.removePreference(allSmsPreference); + if (allMmsPreference != null) preferenceScreen.removePreference(allMmsPreference); + + if (Util.isDefaultSmsProvider(getActivity())) { + defaultPreference.setIntent(new Intent(Settings.ACTION_WIRELESS_SETTINGS)); + defaultPreference.setTitle(getString(R.string.ApplicationPreferencesActivity_sms_enabled)); + defaultPreference.setSummary(getString(R.string.ApplicationPreferencesActivity_touch_to_change_your_default_sms_app)); + } else { + Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT); + intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, getActivity().getPackageName()); + defaultPreference.setIntent(intent); + defaultPreference.setTitle(getString(R.string.ApplicationPreferencesActivity_sms_disabled)); + defaultPreference.setSummary(getString(R.string.ApplicationPreferencesActivity_touch_to_make_textsecure_your_default_sms_app)); + } + } else if (defaultPreference != null) { + preferenceScreen.removePreference(defaultPreference); + } + } + + private void initializeOutgoingSmsSummary(OutgoingSmsPreference pref) { + pref.setSummary(buildOutgoingSmsDescription()); + } + + private class OutgoingSmsPreferenceListener implements Preference.OnPreferenceChangeListener { + + @Override + public boolean onPreferenceChange(final Preference preference, Object newValue) { + + preference.setSummary(buildOutgoingSmsDescription()); + return false; + } + } + + private String buildOutgoingSmsDescription() { + final StringBuilder builder = new StringBuilder(); + final boolean dataFallback = TextSecurePreferences.isFallbackSmsAllowed(getActivity()); + final boolean dataFallbackAsk = TextSecurePreferences.isFallbackSmsAskRequired(getActivity()); + final boolean nonData = TextSecurePreferences.isDirectSmsAllowed(getActivity()); + + if (dataFallback) { + builder.append(getString(R.string.preferences__sms_outgoing_push_users)); + if (dataFallbackAsk) builder.append(" ").append(getString(R.string.preferences__sms_fallback_push_users_ask)); + } + if (nonData) { + if (dataFallback) builder.append(", "); + builder.append(getString(R.string.preferences__sms_fallback_non_push_users)); + } + if (!dataFallback && !nonData) { + builder.append(getString(R.string.preferences__sms_fallback_nobody)); + } + return builder.toString(); + } + + private class ApnPreferencesClickListener implements Preference.OnPreferenceClickListener { + + @Override + public boolean onPreferenceClick(Preference preference) { + Fragment fragment = new MmsPreferencesFragment(); + FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + fragmentTransaction.replace(android.R.id.content, fragment); + fragmentTransaction.addToBackStack(null); + fragmentTransaction.commit(); + + return true; + } + } + + public static CharSequence getSummary(Context context) { + return getIncomingSmsSummary(context) + ", " + getOutgoingSmsSummary(context); + } + + private static CharSequence getIncomingSmsSummary(Context context) { + final int onResId = R.string.ApplicationPreferencesActivity_on; + final int offResId = R.string.ApplicationPreferencesActivity_off; + final int smsResId = R.string.ApplicationPreferencesActivity_sms; + final int mmsResId = R.string.ApplicationPreferencesActivity_mms; + final int incomingSmsResId = R.string.ApplicationPreferencesActivity_incoming_sms; + + final int incomingSmsSummary; + boolean postKitkatSMS = Util.isDefaultSmsProvider(context); + boolean preKitkatSMS = TextSecurePreferences.isInterceptAllSmsEnabled(context); + boolean preKitkatMMS = TextSecurePreferences.isInterceptAllMmsEnabled(context); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + if (postKitkatSMS) incomingSmsSummary = onResId; + else incomingSmsSummary = offResId; + } else { + if (preKitkatSMS && preKitkatMMS) incomingSmsSummary = onResId; + else if (preKitkatSMS && !preKitkatMMS) incomingSmsSummary = smsResId; + else if (!preKitkatSMS && preKitkatMMS) incomingSmsSummary = mmsResId; + else incomingSmsSummary = offResId; + } + return context.getString(incomingSmsResId) + ": " + context.getString(incomingSmsSummary); + } + + private static CharSequence getOutgoingSmsSummary(Context context) { + final int onResId = R.string.ApplicationPreferencesActivity_on; + final int offResId = R.string.ApplicationPreferencesActivity_off; + final int partialResId = R.string.ApplicationPreferencesActivity_partial; + final int outgoingSmsResId = R.string.ApplicationPreferencesActivity_outgoing_sms; + + final int outgoingSmsSummary; + if (TextSecurePreferences.isFallbackSmsAllowed(context) && TextSecurePreferences.isDirectSmsAllowed(context)) { + outgoingSmsSummary = onResId; + } else if (TextSecurePreferences.isFallbackSmsAllowed(context) ^ TextSecurePreferences.isDirectSmsAllowed(context)) { + outgoingSmsSummary = partialResId; + } else { + outgoingSmsSummary = offResId; + } + return context.getString(outgoingSmsResId) + ": " + context.getString(outgoingSmsSummary); + } +} diff --git a/src/org/thoughtcrime/securesms/preferences/StoragePreferenceFragment.java b/src/org/thoughtcrime/securesms/preferences/StoragePreferenceFragment.java new file mode 100644 index 0000000000..ee25cfdb76 --- /dev/null +++ b/src/org/thoughtcrime/securesms/preferences/StoragePreferenceFragment.java @@ -0,0 +1,95 @@ +package org.thoughtcrime.securesms.preferences; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.support.v4.preference.PreferenceFragment; +import android.util.Log; + +import org.thoughtcrime.securesms.ApplicationPreferencesActivity; +import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.util.TextSecurePreferences; +import org.thoughtcrime.securesms.util.Trimmer; + +public class StoragePreferenceFragment extends PreferenceFragment { + private static final String TAG = StoragePreferenceFragment.class.getSimpleName(); + + @Override + public void onCreate(Bundle paramBundle) { + super.onCreate(paramBundle); + addPreferencesFromResource(R.xml.preferences_storage); + + this.findPreference(TextSecurePreferences.THREAD_TRIM_NOW) + .setOnPreferenceClickListener(new TrimNowClickListener()); + this.findPreference(TextSecurePreferences.THREAD_TRIM_LENGTH) + .setOnPreferenceChangeListener(new TrimLengthValidationListener()); + } + + @Override + public void onResume() { + super.onResume(); + ((ApplicationPreferencesActivity) getActivity()).getSupportActionBar().setTitle(R.string.preferences__delete_old_messages); + } + + private class TrimNowClickListener implements Preference.OnPreferenceClickListener { + @Override + public boolean onPreferenceClick(Preference preference) { + final int threadLengthLimit = TextSecurePreferences.getThreadTrimLength(getActivity()); + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.ApplicationPreferencesActivity_delete_all_old_messages_now); + builder.setMessage(getString(R.string.ApplicationPreferencesActivity_are_you_sure_you_would_like_to_immediately_trim_all_conversation_threads_to_the_s_most_recent_messages, + threadLengthLimit)); + builder.setPositiveButton(R.string.ApplicationPreferencesActivity_delete, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Trimmer.trimAllThreads(getActivity(), threadLengthLimit); + } + }); + + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + + return true; + } + } + + private class TrimLengthValidationListener implements Preference.OnPreferenceChangeListener { + + public TrimLengthValidationListener() { + EditTextPreference preference = (EditTextPreference)findPreference(TextSecurePreferences.THREAD_TRIM_LENGTH); + preference.setSummary(getString(R.string.ApplicationPreferencesActivity_messages_per_conversation, preference.getText())); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (newValue == null || ((String)newValue).trim().length() == 0) { + return false; + } + + try { + Integer.parseInt((String)newValue); + } catch (NumberFormatException nfe) { + Log.w(TAG, nfe); + return false; + } + + if (Integer.parseInt((String)newValue) < 1) { + return false; + } + + preference.setSummary(getString(R.string.ApplicationPreferencesActivity_messages_per_conversation, newValue)); + return true; + } + } + + public static CharSequence getSummary(Context context) { + final int onCapsResId = R.string.ApplicationPreferencesActivity_On; + final int offCapsResId = R.string.ApplicationPreferencesActivity_Off; + + return context.getString(TextSecurePreferences.isThreadLengthTrimmingEnabled(context) ? onCapsResId : offCapsResId); + } +}