mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-30 13:35:18 +00:00
Merge pull request #984 from mcginty/sms-prefs
more precise sms controls
This commit is contained in:
commit
938545444e
18
res/drawable/conversation_item_sent_indicator_text_shape.xml
Normal file
18
res/drawable/conversation_item_sent_indicator_text_shape.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#09000000" />
|
||||
<corners android:radius="@dimen/conversation_item_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:bottom="@dimen/conversation_item_drop_shadow_dist">
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/conversation_item_received_background_light" />
|
||||
<corners android:bottomLeftRadius="@dimen/conversation_item_corner_radius" android:bottomRightRadius="@dimen/conversation_item_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#09000000" />
|
||||
<corners android:radius="@dimen/conversation_item_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:bottom="@dimen/conversation_item_drop_shadow_dist">
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/conversation_item_received_background_dark" />
|
||||
<corners android:bottomLeftRadius="@dimen/conversation_item_corner_radius" android:bottomRightRadius="@dimen/conversation_item_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
@ -18,9 +18,10 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="right"
|
||||
android:gravity="left|center_vertical"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_alignParentLeft="true">
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/sms_failed_indicator"
|
||||
@ -29,6 +30,15 @@
|
||||
android:src="@drawable/ic_list_alert_sms_failed"
|
||||
android:visibility="gone"
|
||||
android:contentDescription="Send Failed Indicator"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/pending_approval_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_dialog_info_holo_light"
|
||||
android:visibility="gone"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="Pending Approval"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:id="@+id/conversation_item_parent"
|
||||
@ -190,5 +200,22 @@
|
||||
android:scaleType="centerCrop"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView android:id="@+id/indicator_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/conversation_item_parent"
|
||||
android:layout_alignParentRight="true"
|
||||
android:paddingRight="5dip"
|
||||
android:paddingLeft="5dip"
|
||||
android:paddingTop="3dp"
|
||||
android:paddingBottom="3dp"
|
||||
android:layout_marginLeft="50dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginTop="-2dp"
|
||||
android:textSize="12sp"
|
||||
android:textColor="?conversation_sent_text_secondary_color"
|
||||
android:background="?conversation_item_sent_indicator_text_background"
|
||||
android:visibility="gone" />
|
||||
|
||||
</RelativeLayout>
|
||||
</org.thoughtcrime.securesms.ConversationItem>
|
||||
|
44
res/layout/outgoing_sms_preference.xml
Normal file
44
res/layout/outgoing_sms_preference.xml
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="15dp"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingBottom="15dp"
|
||||
android:paddingRight="10dp">
|
||||
|
||||
<CheckBox android:id="@+id/data_users"
|
||||
style="@style/TextSecureDialogPrimaryText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
|
||||
android:singleLine="true"
|
||||
android:text="@string/preferences__sms_outgoing_push_users" />
|
||||
|
||||
<TextView
|
||||
style="@style/TextSecureDialogSecondaryText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="-5dp"
|
||||
android:layout_marginLeft="32dp"
|
||||
android:textSize="12sp"
|
||||
android:text="@string/preferences__sms_outgoing_push_users_description" />
|
||||
|
||||
<CheckBox android:id="@+id/ask_before_fallback_data"
|
||||
style="@style/TextSecureDialogPrimaryText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
|
||||
android:text="@string/preferences__sms_fallback_ask_fallback"
|
||||
android:layout_marginLeft="25dp" />
|
||||
|
||||
<CheckBox android:id="@+id/non_data_users"
|
||||
style="@style/TextSecureDialogPrimaryText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
|
||||
android:text="@string/preferences__sms_fallback_non_push_users" />
|
||||
|
||||
</LinearLayout>
|
@ -4,4 +4,12 @@
|
||||
<style name="Widget.ProgressBar.Horizontal" parent="@android:style/Widget.Holo.ProgressBar.Horizontal">
|
||||
</style>
|
||||
|
||||
<style name="TextSecureDialogPrimaryText">
|
||||
<item name="android:textColor">?conversation_list_item_contact_color</item>
|
||||
</style>
|
||||
|
||||
<style name="TextSecureDialogSecondaryText">
|
||||
<item name="android:textColor">?conversation_list_item_date_color</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -37,6 +37,7 @@
|
||||
<attr name="conversation_item_sent_pending_triangle_background" format="reference" />
|
||||
<attr name="conversation_item_sent_push_background" format="reference" />
|
||||
<attr name="conversation_item_sent_push_triangle_background" format="reference" />
|
||||
<attr name="conversation_item_sent_indicator_text_background" format="reference" />
|
||||
<attr name="dialog_info_icon" format="reference" />
|
||||
<attr name="dialog_alert_icon" format="reference" />
|
||||
<attr name="conversation_item_sent_push_pending_background" format="reference" />
|
||||
|
@ -32,9 +32,9 @@
|
||||
<string name="ApplicationPreferencesActivity_you_are_not_registered_with_the_push_service">You are not registered with the push service...</string>
|
||||
<string name="ApplicationPreferencesActivity_updating_directory">Updating directory</string>
|
||||
<string name="ApplicationPreferencesActivity_updating_push_directory">Updating push directory...</string>
|
||||
<string name="ApplicationPreferencesActivity_sms_enabled">SMS Enabled</string>
|
||||
<string name="ApplicationPreferencesActivity_sms_enabled">Incoming SMS Enabled</string>
|
||||
<string name="ApplicationPreferencesActivity_touch_to_change_your_default_sms_app">Touch to change your default SMS app</string>
|
||||
<string name="ApplicationPreferencesActivity_sms_disabled">SMS Disabled</string>
|
||||
<string name="ApplicationPreferencesActivity_sms_disabled">Incoming SMS Disabled</string>
|
||||
<string name="ApplicationPreferencesActivity_touch_to_make_textsecure_your_default_sms_app">Touch to make TextSecure your default SMS app</string>
|
||||
|
||||
<!-- AttachmentTypeSelectorAdapter -->
|
||||
@ -63,6 +63,8 @@
|
||||
<string name="ConversationItem_group_action_left">%1$s has left the group.</string>
|
||||
<string name="ConversationItem_group_action_joined">%1$s have joined the group.</string>
|
||||
<string name="ConversationItem_group_action_modify">%1$s has updated the group.</string>
|
||||
<string name="ConversationItem_click_to_approve">Tap for SMS fallback</string>
|
||||
<string name="ConversationItem_click_to_approve_dialog_title">Fallback to SMS?</string>
|
||||
|
||||
<!-- ConversationActivity -->
|
||||
<string name="ConversationActivity_initiate_secure_session_question">Initiate Secure Session?</string>
|
||||
@ -642,8 +644,9 @@
|
||||
|
||||
<!-- preferences.xml -->
|
||||
<string name="preferences__general">General</string>
|
||||
<string name="preferences__pref_all_sms_title">Use for all SMS</string>
|
||||
<string name="preferences__pref_all_mms_title">Use for all MMS</string>
|
||||
<string name="preferences__push_sms_category">Push and SMS</string>
|
||||
<string name="preferences__pref_all_sms_title">Receive all SMS</string>
|
||||
<string name="preferences__pref_all_mms_title">Receive all MMS</string>
|
||||
<string name="preferences__use_textsecure_for_viewing_and_storing_all_incoming_text_messages">Use TextSecure for viewing and storing all incoming text messages</string>
|
||||
<string name="preferences__use_textsecure_for_viewing_and_storing_all_incoming_multimedia_messages">Use TextSecure for viewing and storing all incoming multimedia messages</string>
|
||||
<string name="preferences__enable_enter_key_title">Enable Enter key</string>
|
||||
@ -726,11 +729,16 @@
|
||||
<string name="preferences__use_the_data_channel_for_communication_with_other_textsecure_users">
|
||||
Increase privacy and avoid SMS fees by using the data channel for communication with other TextSecure users
|
||||
</string>
|
||||
<string name="preferences__allow_sms_fallback">SMS Fallback</string>
|
||||
<string name="preferences__allow_sms_fallback">Allow outgoing SMS to</string>
|
||||
<string name="preferences__allow_sms_fallback_disabled_reason">TextSecure is currently your default SMS app. Please set another default SMS app first to change this preference.</string>
|
||||
<string name="preferences__send_and_receive_sms_messages_when_push_is_not_available">Send and receive SMS messages when push is not available</string>
|
||||
<string name="preferences__refresh_push_directory">Refresh Push Directory</string>
|
||||
<string name="preferences__submit_debug_log">Submit debug log</string>
|
||||
<string name="preferences__sms_outgoing_push_users">TextSecure users</string>
|
||||
<string name="preferences__sms_fallback_push_users_ask">(ask first)</string>
|
||||
<string name="preferences__sms_outgoing_push_users_description">Send secure SMS if data connectivity is lost</string>
|
||||
<string name="preferences__sms_fallback_ask_fallback">Ask before sending SMS</string>
|
||||
<string name="preferences__sms_fallback_non_push_users">Non-TextSecure users</string>
|
||||
<string name="preferences__sms_fallback_nobody">Nobody</string>
|
||||
|
||||
<!-- **************************************** -->
|
||||
<!-- menus -->
|
||||
|
@ -107,4 +107,13 @@
|
||||
|
||||
<style name="Widget.ProgressBar.Horizontal" parent="@android:style/Widget.ProgressBar.Horizontal">
|
||||
</style>
|
||||
|
||||
<style name="TextSecureDialogPrimaryText">
|
||||
<item name="android:textColor">@color/white</item>
|
||||
</style>
|
||||
|
||||
<style name="TextSecureDialogSecondaryText">
|
||||
<item name="android:textColor">#ff999999</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
@ -39,6 +39,7 @@
|
||||
<item name="conversation_item_sent_triangle_background">@drawable/conversation_item_sent_triangle_shape</item>
|
||||
<item name="conversation_item_sent_push_background">@drawable/conversation_item_sent_push_shape</item>
|
||||
<item name="conversation_item_sent_push_triangle_background">@drawable/conversation_item_sent_push_triangle_shape</item>
|
||||
<item name="conversation_item_sent_indicator_text_background">@drawable/conversation_item_sent_indicator_text_shape</item>
|
||||
<item name="dialog_info_icon">@drawable/ic_dialog_info_light</item>
|
||||
<item name="dialog_alert_icon">@drawable/ic_dialog_alert_light</item>
|
||||
<item name="conversation_item_sent_pending_background">@drawable/conversation_item_sent_pending_shape</item>
|
||||
@ -59,7 +60,6 @@
|
||||
<item name="menu_split_icon">@drawable/ic_menu_split_holo_light</item>
|
||||
<item name="menu_accept_icon">@drawable/ic_menu_accept_holo_light</item>
|
||||
<item name="menu_refresh_directory">@drawable/ic_menu_refresh_holo_light</item>
|
||||
|
||||
</style>
|
||||
|
||||
<style name="TextSecure.LightTheme.NavigationDrawer"
|
||||
@ -100,6 +100,7 @@
|
||||
<item name="conversation_item_sent_triangle_background">@drawable/conversation_item_sent_triangle_shape_dark</item>
|
||||
<item name="conversation_item_sent_push_background">@drawable/conversation_item_sent_push_shape_dark</item>
|
||||
<item name="conversation_item_sent_push_triangle_background">@drawable/conversation_item_sent_push_triangle_shape_dark</item>
|
||||
<item name="conversation_item_sent_indicator_text_background">@drawable/conversation_item_sent_indicator_text_shape_dark</item>
|
||||
<item name="dialog_info_icon">@drawable/ic_dialog_info_dark</item>
|
||||
<item name="dialog_alert_icon">@drawable/ic_dialog_alert_dark</item>
|
||||
<item name="conversation_item_sent_pending_background">@drawable/conversation_item_sent_pending_shape_dark</item>
|
||||
|
@ -1,7 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceCategory android:key="general_category" android:title="@string/preferences__general">
|
||||
<PreferenceCategory android:key="push_sms_category" android:title="@string/preferences__push_sms_category">
|
||||
<CheckBoxPreference android:defaultValue="false"
|
||||
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"/>
|
||||
|
||||
<CheckBoxPreference android:defaultValue="true"
|
||||
android:key="pref_all_sms"
|
||||
android:summary="@string/preferences__use_textsecure_for_viewing_and_storing_all_incoming_text_messages"
|
||||
@ -16,22 +21,14 @@
|
||||
android:title="@string/preferences__make_default_sms_app"
|
||||
android:summary="@string/preferences__make_textsecure_the_default_sms_mms_app" />
|
||||
|
||||
<CheckBoxPreference android:defaultValue="false"
|
||||
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"/>
|
||||
|
||||
<CheckBoxPreference android:defaultValue="true"
|
||||
android:enabled="false"
|
||||
android:key="pref_allow_sms_traffic_out"
|
||||
android:title="@string/preferences__allow_sms_fallback"
|
||||
android:summary="@string/preferences__send_and_receive_sms_messages_when_push_is_not_available"/>
|
||||
<org.thoughtcrime.securesms.components.OutgoingSmsPreference
|
||||
android:key="pref_outgoing_sms"
|
||||
android:title="@string/preferences__allow_sms_fallback" />
|
||||
|
||||
<CheckBoxPreference android:defaultValue="false"
|
||||
android:key="pref_delivery_report_sms"
|
||||
android:summary="@string/preferences__request_a_delivery_report_for_each_sms_message_you_send"
|
||||
android:title="@string/preferences__sms_delivery_reports" />
|
||||
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/preferences__notifications">
|
||||
<CheckBoxPreference android:key="pref_key_enable_notifications"
|
||||
|
@ -47,6 +47,7 @@ import android.widget.Toast;
|
||||
import com.actionbarsherlock.view.MenuItem;
|
||||
import com.google.android.gcm.GCMRegistrar;
|
||||
|
||||
import org.thoughtcrime.securesms.components.OutgoingSmsPreference;
|
||||
import org.thoughtcrime.securesms.contacts.ContactAccessor;
|
||||
import org.thoughtcrime.securesms.contacts.ContactIdentityManager;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
|
||||
@ -77,6 +78,7 @@ import java.io.IOException;
|
||||
public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPreferenceActivity
|
||||
implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
{
|
||||
private static final String TAG = "Preferences";
|
||||
|
||||
private static final int PICK_IDENTITY_CONTACT = 1;
|
||||
private static final int ENABLE_PASSPHRASE_ACTIVITY = 2;
|
||||
@ -87,6 +89,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
private static final String KITKAT_DEFAULT_PREF = "pref_set_default";
|
||||
private static final String UPDATE_DIRECTORY_PREF = "pref_update_directory";
|
||||
private static final String SUBMIT_DEBUG_LOG_PREF = "pref_submit_debug_logs";
|
||||
private static final String OUTGOING_SMS_PREF = "pref_outgoing_sms";
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
||||
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||
@ -103,7 +106,6 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
|
||||
initializeIdentitySelection();
|
||||
initializeSmsFallbackOption();
|
||||
initializePushMessagingToggle();
|
||||
|
||||
this.findPreference(TextSecurePreferences.CHANGE_PASSPHRASE_PREF)
|
||||
@ -126,7 +128,10 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
.setOnPreferenceClickListener(new DirectoryUpdateListener());
|
||||
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));
|
||||
@ -188,14 +193,14 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
}
|
||||
|
||||
private void initializePlatformSpecificOptions() {
|
||||
PreferenceGroup generalCategory = (PreferenceGroup) findPreference("general_category");
|
||||
PreferenceGroup pushSmsCategory = (PreferenceGroup) findPreference("push_sms_category");
|
||||
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) generalCategory.removePreference(allSmsPreference);
|
||||
if (allMmsPreference != null) generalCategory.removePreference(allMmsPreference);
|
||||
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(this)) {
|
||||
defaultPreference.setIntent(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
|
||||
@ -208,36 +213,8 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
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) generalCategory.removePreference(defaultPreference);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeSmsFallbackOption() {
|
||||
CheckBoxPreference allowSmsPreference =
|
||||
(CheckBoxPreference) findPreference(TextSecurePreferences.ALLOW_SMS_FALLBACK_PREF);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
if (Util.isDefaultSmsProvider(this) || !TextSecurePreferences.isPushRegistered(this)) {
|
||||
allowSmsPreference.setEnabled(false);
|
||||
allowSmsPreference.setChecked(true);
|
||||
allowSmsPreference.setSummary(R.string.preferences__allow_sms_fallback_disabled_reason);
|
||||
} else {
|
||||
allowSmsPreference.setEnabled(true);
|
||||
allowSmsPreference.setSummary(R.string.preferences__send_and_receive_sms_messages_when_push_is_not_available);
|
||||
}
|
||||
} else {
|
||||
if (TextSecurePreferences.isInterceptAllMmsEnabled(this) ||
|
||||
TextSecurePreferences.isInterceptAllSmsEnabled(this) ||
|
||||
!TextSecurePreferences.isPushRegistered(this))
|
||||
{
|
||||
allowSmsPreference.setEnabled(false);
|
||||
allowSmsPreference.setChecked(true);
|
||||
allowSmsPreference.setSummary(R.string.preferences__allow_sms_fallback_disabled_reason);
|
||||
} else {
|
||||
allowSmsPreference.setEnabled(true);
|
||||
allowSmsPreference.setSummary(R.string.preferences__send_and_receive_sms_messages_when_push_is_not_available);
|
||||
}
|
||||
} else if (pushSmsCategory != null && defaultPreference != null) {
|
||||
pushSmsCategory.removePreference(defaultPreference);
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,6 +273,10 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
listener.onPreferenceChange(pref, sharedPreferences.getString(pref.getKey(), ""));
|
||||
}
|
||||
|
||||
private void initializeOutgoingSmsSummary(OutgoingSmsPreference pref) {
|
||||
pref.setSummary(buildOutgoingSmsDescription());
|
||||
}
|
||||
|
||||
private void handleIdentitySelection(Intent data) {
|
||||
Uri contactUri = data.getData();
|
||||
|
||||
@ -311,11 +292,6 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
dynamicTheme.onResume(this);
|
||||
} else if (key.equals(TextSecurePreferences.LANGUAGE_PREF)) {
|
||||
dynamicLanguage.onResume(this);
|
||||
} else if (key.equals(TextSecurePreferences.ALL_MMS_PREF) ||
|
||||
key.equals(TextSecurePreferences.ALL_SMS_PREF) ||
|
||||
key.equals(TextSecurePreferences.REGISTERED_GCM_PREF))
|
||||
{
|
||||
initializeSmsFallbackOption();
|
||||
}
|
||||
}
|
||||
|
||||
@ -614,6 +590,36 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
}
|
||||
}
|
||||
|
||||
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.isSmsFallbackEnabled(this);
|
||||
final boolean dataFallbackAsk = TextSecurePreferences.isSmsFallbackAskEnabled(this);
|
||||
final boolean nonData = TextSecurePreferences.isSmsNonDataOutEnabled(this);
|
||||
|
||||
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
|
||||
|
@ -44,7 +44,9 @@ import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord;
|
||||
@ -107,12 +109,15 @@ public class ConversationItem extends LinearLayout {
|
||||
private View conversationParent;
|
||||
private TextView bodyText;
|
||||
private TextView dateText;
|
||||
private TextView indicatorText;
|
||||
private TextView groupStatusText;
|
||||
private ImageView secureImage;
|
||||
private ImageView failedImage;
|
||||
private ImageView keyImage;
|
||||
private ImageView contactPhoto;
|
||||
private ImageView deliveredImage;
|
||||
private View triangleTick;
|
||||
private ImageView pendingIndicator;
|
||||
|
||||
private View mmsContainer;
|
||||
private ImageView mmsThumbnail;
|
||||
@ -144,6 +149,7 @@ public class ConversationItem extends LinearLayout {
|
||||
|
||||
this.bodyText = (TextView) findViewById(R.id.conversation_item_body);
|
||||
this.dateText = (TextView) findViewById(R.id.conversation_item_date);
|
||||
this.indicatorText = (TextView) findViewById(R.id.indicator_text);
|
||||
this.groupStatusText = (TextView) findViewById(R.id.group_message_status);
|
||||
this.secureImage = (ImageView)findViewById(R.id.sms_secure_indicator);
|
||||
this.failedImage = (ImageView)findViewById(R.id.sms_failed_indicator);
|
||||
@ -155,6 +161,8 @@ public class ConversationItem extends LinearLayout {
|
||||
this.contactPhoto = (ImageView)findViewById(R.id.contact_photo);
|
||||
this.deliveredImage = (ImageView)findViewById(R.id.delivered_indicator);
|
||||
this.conversationParent = (View) findViewById(R.id.conversation_item_parent);
|
||||
this.triangleTick = findViewById(R.id.triangle_tick);
|
||||
this.pendingIndicator = (ImageView)findViewById(R.id.pending_approval_indicator);
|
||||
this.backgroundDrawables = context.obtainStyledAttributes(STYLE_ATTRIBUTES);
|
||||
|
||||
setOnClickListener(clickListener);
|
||||
@ -180,6 +188,7 @@ public class ConversationItem extends LinearLayout {
|
||||
setContactPhoto(messageRecord);
|
||||
setGroupMessageStatus(messageRecord);
|
||||
setEvents(messageRecord);
|
||||
setMinimumWidth();
|
||||
|
||||
if (messageRecord instanceof NotificationMmsMessageRecord) {
|
||||
setNotificationMmsAttributes((NotificationMmsMessageRecord)messageRecord);
|
||||
@ -218,10 +227,10 @@ public class ConversationItem extends LinearLayout {
|
||||
if (messageRecord.isOutgoing()) {
|
||||
final int background;
|
||||
final int triangleBackground;
|
||||
if (messageRecord.isPending() && pushDestination) {
|
||||
if (messageRecord.isPending() && pushDestination && !messageRecord.isForcedSms()) {
|
||||
background = SENT_PUSH_PENDING;
|
||||
triangleBackground = SENT_PUSH_PENDING_TRIANGLE;
|
||||
} else if (messageRecord.isPending()) {
|
||||
} else if (messageRecord.isPending() || messageRecord.isPendingFallbackApproval()) {
|
||||
background = SENT_SMS_PENDING;
|
||||
triangleBackground = SENT_SMS_PENDING_TRIANGLE;
|
||||
} else if (messageRecord.isPush()) {
|
||||
@ -232,7 +241,7 @@ public class ConversationItem extends LinearLayout {
|
||||
triangleBackground = SENT_SMS_TRIANGLE;
|
||||
}
|
||||
setViewBackgroundWithoutResettingPadding(conversationParent, backgroundDrawables.getResourceId(background, -1));
|
||||
setViewBackgroundWithoutResettingPadding(findViewById(R.id.triangle_tick), backgroundDrawables.getResourceId(triangleBackground, -1));
|
||||
setViewBackgroundWithoutResettingPadding(triangleTick, backgroundDrawables.getResourceId(triangleBackground, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -255,6 +264,10 @@ public class ConversationItem extends LinearLayout {
|
||||
|
||||
private void setStatusIcons(MessageRecord messageRecord) {
|
||||
failedImage.setVisibility(messageRecord.isFailed() ? View.VISIBLE : View.GONE);
|
||||
if (messageRecord.isOutgoing()) {
|
||||
pendingIndicator.setVisibility(messageRecord.isPendingFallbackApproval() ? View.VISIBLE : View.GONE);
|
||||
indicatorText.setVisibility(messageRecord.isPendingFallbackApproval() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
secureImage.setVisibility(messageRecord.isSecure() ? View.VISIBLE : View.GONE);
|
||||
keyImage.setVisibility(messageRecord.isKeyExchange() ? View.VISIBLE : View.GONE);
|
||||
deliveredImage.setVisibility(!messageRecord.isKeyExchange() && messageRecord.isDelivered() ? View.VISIBLE : View.GONE);
|
||||
@ -265,6 +278,9 @@ public class ConversationItem extends LinearLayout {
|
||||
|
||||
if (messageRecord.isFailed()) {
|
||||
dateText.setText(R.string.ConversationItem_error_sending_message);
|
||||
} else if (messageRecord.isPendingFallbackApproval() && indicatorText != null) {
|
||||
dateText.setText("");
|
||||
indicatorText.setText(R.string.ConversationItem_click_to_approve);
|
||||
} else if (messageRecord.isPending()) {
|
||||
dateText.setText(" ··· ");
|
||||
} else {
|
||||
@ -276,10 +292,19 @@ public class ConversationItem extends LinearLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private void setMinimumWidth() {
|
||||
if (indicatorText != null && indicatorText.getVisibility() == View.VISIBLE && indicatorText.getText() != null) {
|
||||
conversationParent.setMinimumWidth(indicatorText.getText().length() * 20);
|
||||
} else {
|
||||
conversationParent.setMinimumWidth(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void setEvents(MessageRecord messageRecord) {
|
||||
setClickable(messageRecord.isKeyExchange() &&
|
||||
!messageRecord.isCorruptedKeyExchange() &&
|
||||
!messageRecord.isOutgoing());
|
||||
setClickable(messageRecord.isPendingFallbackApproval() ||
|
||||
(messageRecord.isKeyExchange() &&
|
||||
!messageRecord.isCorruptedKeyExchange() &&
|
||||
!messageRecord.isOutgoing()));
|
||||
|
||||
if (!messageRecord.isOutgoing() &&
|
||||
messageRecord.getRecipients().isSingleRecipient() &&
|
||||
@ -615,9 +640,42 @@ public class ConversationItem extends LinearLayout {
|
||||
!messageRecord.isProcessedKeyExchange() &&
|
||||
!messageRecord.isStaleKeyExchange())
|
||||
handleKeyExchangeClicked();
|
||||
else if (messageRecord.isPendingFallbackApproval())
|
||||
handleMessageApproval();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMessageApproval() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(R.string.ConversationItem_click_to_approve_dialog_title);
|
||||
builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
if (messageRecord.isMms()) {
|
||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||
database.markAsOutbox(messageRecord.getId());
|
||||
database.markAsForcedSms(messageRecord.getId());
|
||||
} else {
|
||||
SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
|
||||
database.markAsOutbox(messageRecord.getId());
|
||||
database.markAsForcedSms(messageRecord.getId());
|
||||
}
|
||||
Intent intent = new Intent(context, SendReceiveService.class);
|
||||
intent.setAction(SendReceiveService.SEND_SMS_ACTION);
|
||||
intent.putExtra(SendReceiveService.MASTER_SECRET_EXTRA, masterSecret);
|
||||
context.startService(intent);
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
if (messageRecord.isMms()) DatabaseFactory.getMmsDatabase(context).markAsSentFailed(messageRecord.getId());
|
||||
else DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageRecord.getId());
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void handleAbortSecureSession() {
|
||||
if (!messageRecord.isSecure()) return;
|
||||
|
||||
|
@ -159,7 +159,7 @@ public class PushContactSelectionListFragment extends SherlockListFragment
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.ContactSelectionlistFragment_select_for + " " + contactData.name);
|
||||
builder.setTitle(getString(R.string.ContactSelectionlistFragment_select_for) + " " + contactData.name);
|
||||
builder.setMultiChoiceItems(options, null, new DiscriminatorClickedListener(contactData));
|
||||
builder.setPositiveButton(android.R.string.ok, new DiscriminatorFinishedListener(contactData, textView, checkBox));
|
||||
builder.setOnCancelListener(new DiscriminatorFinishedListener(contactData, textView, checkBox));
|
||||
|
@ -0,0 +1,54 @@
|
||||
package org.thoughtcrime.securesms.components;
|
||||
|
||||
import android.content.Context;
|
||||
import android.preference.DialogPreference;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
public class OutgoingSmsPreference extends DialogPreference {
|
||||
private CheckBox dataUsers;
|
||||
private CheckBox askForFallback;
|
||||
private CheckBox nonDataUsers;
|
||||
public OutgoingSmsPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setPersistent(false);
|
||||
setDialogLayoutResource(R.layout.outgoing_sms_preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindDialogView(final View view) {
|
||||
super.onBindDialogView(view);
|
||||
dataUsers = (CheckBox) view.findViewById(R.id.data_users);
|
||||
askForFallback = (CheckBox) view.findViewById(R.id.ask_before_fallback_data);
|
||||
nonDataUsers = (CheckBox) view.findViewById(R.id.non_data_users);
|
||||
|
||||
dataUsers.setChecked(TextSecurePreferences.isSmsFallbackEnabled(getContext()));
|
||||
askForFallback.setChecked(TextSecurePreferences.isSmsFallbackAskEnabled(getContext()));
|
||||
nonDataUsers.setChecked(TextSecurePreferences.isSmsNonDataOutEnabled(getContext()));
|
||||
|
||||
dataUsers.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
askForFallback.setEnabled(dataUsers.isChecked());
|
||||
}
|
||||
});
|
||||
|
||||
askForFallback.setEnabled(dataUsers.isChecked());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDialogClosed(boolean positiveResult) {
|
||||
super.onDialogClosed(positiveResult);
|
||||
|
||||
if (positiveResult) {
|
||||
TextSecurePreferences.setSmsFallbackEnabled(getContext(), dataUsers.isChecked());
|
||||
TextSecurePreferences.setSmsFallbackAskEnabled(getContext(), askForFallback.isChecked());
|
||||
TextSecurePreferences.setSmsNonDataOutEnabled(getContext(), nonDataUsers.isChecked());
|
||||
if (getOnPreferenceChangeListener() != null) getOnPreferenceChangeListener().onPreferenceChange(this, null);
|
||||
}
|
||||
}
|
||||
}
|
@ -281,6 +281,15 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
||||
notifyConversationListeners(getThreadIdForMessage(messageId));
|
||||
}
|
||||
|
||||
public void markAsForcedSms(long id) {
|
||||
updateMailboxBitmask(id, 0, Types.MESSAGE_FORCE_SMS_BIT);
|
||||
}
|
||||
|
||||
public void markAsPendingApproval(long messageId) {
|
||||
updateMailboxBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_PENDING_FALLBACK_APPROVAL);
|
||||
notifyConversationListeners(getThreadIdForMessage(messageId));
|
||||
}
|
||||
|
||||
public void markAsSending(long messageId) {
|
||||
updateMailboxBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_SENDING_TYPE);
|
||||
notifyConversationListeners(getThreadIdForMessage(messageId));
|
||||
|
@ -15,16 +15,22 @@ public interface MmsSmsColumns {
|
||||
protected static final long TOTAL_MASK = 0xFFFFFFFF;
|
||||
|
||||
// Base Types
|
||||
protected static final long BASE_TYPE_MASK = 0xFF;
|
||||
protected static final long BASE_TYPE_MASK = 0x1F;
|
||||
|
||||
protected static final long BASE_INBOX_TYPE = 20;
|
||||
protected static final long BASE_OUTBOX_TYPE = 21;
|
||||
protected static final long BASE_SENDING_TYPE = 22;
|
||||
protected static final long BASE_SENT_TYPE = 23;
|
||||
protected static final long BASE_SENT_FAILED_TYPE = 24;
|
||||
protected static final long BASE_INBOX_TYPE = 20;
|
||||
protected static final long BASE_OUTBOX_TYPE = 21;
|
||||
protected static final long BASE_SENDING_TYPE = 22;
|
||||
protected static final long BASE_SENT_TYPE = 23;
|
||||
protected static final long BASE_SENT_FAILED_TYPE = 24;
|
||||
protected static final long BASE_PENDING_FALLBACK_APPROVAL = 25;
|
||||
|
||||
protected static final long[] OUTGOING_MESSAGE_TYPES = {BASE_OUTBOX_TYPE, BASE_SENT_TYPE,
|
||||
BASE_SENDING_TYPE, BASE_SENT_FAILED_TYPE};
|
||||
BASE_SENDING_TYPE, BASE_SENT_FAILED_TYPE,
|
||||
BASE_PENDING_FALLBACK_APPROVAL};
|
||||
|
||||
// Message attributes
|
||||
protected static final long MESSAGE_ATTRIBUTE_MASK = 0xE0;
|
||||
protected static final long MESSAGE_FORCE_SMS_BIT = 0x40;
|
||||
|
||||
// Key Exchange Information
|
||||
protected static final long KEY_EXCHANGE_BIT = 0x8000;
|
||||
@ -65,12 +71,20 @@ public interface MmsSmsColumns {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isForcedSms(long type) {
|
||||
return (type & MESSAGE_FORCE_SMS_BIT) != 0;
|
||||
}
|
||||
|
||||
public static boolean isPendingMessageType(long type) {
|
||||
return
|
||||
(type & BASE_TYPE_MASK) == BASE_OUTBOX_TYPE ||
|
||||
(type & BASE_TYPE_MASK) == BASE_SENDING_TYPE;
|
||||
}
|
||||
|
||||
public static boolean isPendingApprovalType(long type) {
|
||||
return (type & BASE_TYPE_MASK) == BASE_PENDING_FALLBACK_APPROVAL;
|
||||
}
|
||||
|
||||
public static boolean isInboxType(long type) {
|
||||
return (type & BASE_TYPE_MASK) == BASE_INBOX_TYPE;
|
||||
}
|
||||
|
@ -178,6 +178,10 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
|
||||
updateTypeBitmask(id, 0, Types.PUSH_MESSAGE_BIT);
|
||||
}
|
||||
|
||||
public void markAsForcedSms(long id) {
|
||||
updateTypeBitmask(id, 0, Types.MESSAGE_FORCE_SMS_BIT);
|
||||
}
|
||||
|
||||
public void markAsDecryptFailed(long id) {
|
||||
updateTypeBitmask(id, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_FAILED_BIT);
|
||||
}
|
||||
@ -194,6 +198,10 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
|
||||
updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.BASE_OUTBOX_TYPE);
|
||||
}
|
||||
|
||||
public void markAsPendingApproval(long id) {
|
||||
updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.BASE_PENDING_FALLBACK_APPROVAL);
|
||||
}
|
||||
|
||||
public void markAsSending(long id) {
|
||||
updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.BASE_SENDING_TYPE);
|
||||
}
|
||||
|
@ -113,6 +113,10 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
return SmsDatabase.Types.isPushType(type);
|
||||
}
|
||||
|
||||
public boolean isForcedSms() {
|
||||
return SmsDatabase.Types.isForcedSms(type);
|
||||
}
|
||||
|
||||
public boolean isStaleKeyExchange() {
|
||||
return SmsDatabase.Types.isStaleKeyExchange(type);
|
||||
}
|
||||
@ -121,6 +125,10 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
return SmsDatabase.Types.isProcessedKeyExchange(type);
|
||||
}
|
||||
|
||||
public boolean isPendingFallbackApproval() {
|
||||
return SmsDatabase.Types.isPendingApprovalType(type);
|
||||
}
|
||||
|
||||
public boolean isBundleKeyExchange() {
|
||||
return SmsDatabase.Types.isBundleKeyExchange(type);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
||||
import org.thoughtcrime.securesms.transport.UniversalTransport;
|
||||
import org.thoughtcrime.securesms.transport.UntrustedIdentityException;
|
||||
import org.thoughtcrime.securesms.transport.UserInterventionRequiredException;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
|
||||
import ws.com.google.android.mms.MmsException;
|
||||
@ -83,6 +84,11 @@ public class MmsSender {
|
||||
result.getResponseStatus());
|
||||
|
||||
systemStateListener.unregisterForConnectivityChange();
|
||||
} catch (UserInterventionRequiredException uire) {
|
||||
Log.w("MmsSender", uire);
|
||||
database.markAsPendingApproval(message.getDatabaseMessageId());
|
||||
Recipients recipients = threads.getRecipientsForThreadId(threadId);
|
||||
MessageNotifier.notifyMessageDeliveryFailed(context, recipients, threadId);
|
||||
} catch (UndeliverableMessageException e) {
|
||||
Log.w("MmsSender", e);
|
||||
database.markAsSentFailed(message.getDatabaseMessageId());
|
||||
|
@ -62,6 +62,8 @@ public class SendReceiveService extends Service {
|
||||
public static final String DOWNLOAD_PUSH_ACTION = "org.thoughtcrime.securesms.SendReceiveService.DOWNLOAD_PUSH_ACTION";
|
||||
public static final String DOWNLOAD_AVATAR_ACTION = "org.thoughtcrime.securesms.SendReceiveService.DOWNLOAD_AVATAR_ACTION";
|
||||
|
||||
public static final String MASTER_SECRET_EXTRA = "master_secret";
|
||||
|
||||
private static final int SEND_SMS = 0;
|
||||
private static final int RECEIVE_SMS = 1;
|
||||
private static final int SEND_MMS = 2;
|
||||
@ -307,7 +309,7 @@ public class SendReceiveService extends Service {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.w("SendReceiveService", "Got a MasterSecret broadcast...");
|
||||
initializeWithMasterSecret((MasterSecret)intent.getParcelableExtra("master_secret"));
|
||||
initializeWithMasterSecret((MasterSecret)intent.getParcelableExtra(MASTER_SECRET_EXTRA));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,8 @@ import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
||||
import org.thoughtcrime.securesms.transport.UniversalTransport;
|
||||
import org.thoughtcrime.securesms.transport.UntrustedIdentityException;
|
||||
import org.thoughtcrime.securesms.transport.UserInterventionRequiredException;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.storage.Session;
|
||||
|
||||
@ -84,6 +86,10 @@ public class SmsSender {
|
||||
database.markAsSending(record.getId());
|
||||
|
||||
transport.deliver(record);
|
||||
} catch (UserInterventionRequiredException uire) {
|
||||
Log.w("SmsSender", uire);
|
||||
DatabaseFactory.getSmsDatabase(context).markAsPendingApproval(record.getId());
|
||||
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipients(), record.getThreadId());
|
||||
} catch (UntrustedIdentityException e) {
|
||||
Log.w("SmsSender", e);
|
||||
IncomingIdentityUpdateMessage identityUpdateMessage = IncomingIdentityUpdateMessage.createFor(e.getE164Number(), e.getIdentityKey());
|
||||
@ -92,6 +98,7 @@ public class SmsSender {
|
||||
} catch (UndeliverableMessageException ude) {
|
||||
Log.w("SmsSender", ude);
|
||||
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(record.getId());
|
||||
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipients(), record.getThreadId());
|
||||
} catch (RetryLaterException rle) {
|
||||
Log.w("SmsSender", rle);
|
||||
DatabaseFactory.getSmsDatabase(context).markAsOutbox(record.getId());
|
||||
|
@ -48,9 +48,7 @@ public class SmsTransport extends BaseTransport {
|
||||
}
|
||||
|
||||
public void deliver(SmsMessageRecord message) throws UndeliverableMessageException {
|
||||
if (TextSecurePreferences.isPushRegistered(context) &&
|
||||
!TextSecurePreferences.isSmsFallbackEnabled(context))
|
||||
{
|
||||
if (!TextSecurePreferences.isSmsNonDataOutEnabled(context) && !TextSecurePreferences.isSmsFallbackEnabled(context)) {
|
||||
throw new UndeliverableMessageException("SMS Transport is not enabled!");
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ public class UniversalTransport {
|
||||
}
|
||||
|
||||
public void deliver(SmsMessageRecord message)
|
||||
throws UndeliverableMessageException, UntrustedIdentityException, RetryLaterException
|
||||
throws UndeliverableMessageException, UntrustedIdentityException, RetryLaterException, UserInterventionRequiredException
|
||||
{
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
smsTransport.deliver(message);
|
||||
@ -71,23 +71,25 @@ public class UniversalTransport {
|
||||
Recipient recipient = message.getIndividualRecipient();
|
||||
String number = Util.canonicalizeNumber(context, recipient.getNumber());
|
||||
|
||||
if (isPushTransport(number) && !message.isKeyExchange()) {
|
||||
if (isPushTransport(number) && !message.isKeyExchange() && !message.isForcedSms()) {
|
||||
boolean isSmsFallbackSupported = isSmsFallbackSupported(number);
|
||||
|
||||
try {
|
||||
Log.w("UniversalTransport", "Delivering with GCM...");
|
||||
Log.w("UniversalTransport", "Using GCM as transport...");
|
||||
pushTransport.deliver(message);
|
||||
} catch (UnregisteredUserException uue) {
|
||||
Log.w("UnviersalTransport", uue);
|
||||
if (isSmsFallbackSupported) smsTransport.deliver(message);
|
||||
Log.w("UniversalTransport", uue);
|
||||
if (isSmsFallbackSupported) fallbackOrAskApproval(message, number);
|
||||
else throw new UndeliverableMessageException(uue);
|
||||
} catch (IOException ioe) {
|
||||
Log.w("UniversalTransport", ioe);
|
||||
if (isSmsFallbackSupported) smsTransport.deliver(message);
|
||||
if (isSmsFallbackSupported) fallbackOrAskApproval(message, number);
|
||||
else throw new RetryLaterException(ioe);
|
||||
}
|
||||
} else if (!message.isForcedSms() && !TextSecurePreferences.isSmsNonDataOutEnabled(context)) {
|
||||
throw new UndeliverableMessageException("User disallows non-push outgoing SMS");
|
||||
} else {
|
||||
Log.w("UniversalTransport", "Delivering with SMS...");
|
||||
Log.w("UniversalTransport", "Using SMS as transport...");
|
||||
smsTransport.deliver(message);
|
||||
}
|
||||
} catch (InvalidNumberException e) {
|
||||
@ -97,7 +99,7 @@ public class UniversalTransport {
|
||||
}
|
||||
|
||||
public MmsSendResult deliver(SendReq mediaMessage, long threadId)
|
||||
throws UndeliverableMessageException, RetryLaterException, UntrustedIdentityException
|
||||
throws UndeliverableMessageException, RetryLaterException, UntrustedIdentityException, UserInterventionRequiredException
|
||||
{
|
||||
if (Util.isEmpty(mediaMessage.getTo())) {
|
||||
return mmsTransport.deliver(mediaMessage);
|
||||
@ -122,16 +124,16 @@ public class UniversalTransport {
|
||||
boolean isSmsFallbackSupported = isSmsFallbackSupported(destination);
|
||||
|
||||
try {
|
||||
Log.w("UniversalTransport", "Delivering media message with GCM...");
|
||||
Log.w("UniversalTransport", "Using GCM as transport...");
|
||||
pushTransport.deliver(mediaMessage, threadId);
|
||||
return new MmsSendResult("push".getBytes("UTF-8"), 0, true, true);
|
||||
} catch (IOException ioe) {
|
||||
Log.w("UniversalTransport", ioe);
|
||||
if (isSmsFallbackSupported) return mmsTransport.deliver(mediaMessage);
|
||||
if (isSmsFallbackSupported) return fallbackOrAskApproval(mediaMessage, destination);
|
||||
else throw new RetryLaterException(ioe);
|
||||
} catch (RecipientFormattingException e) {
|
||||
Log.w("UniversalTransport", e);
|
||||
if (isSmsFallbackSupported) return mmsTransport.deliver(mediaMessage);
|
||||
if (isSmsFallbackSupported) return fallbackOrAskApproval(mediaMessage, destination);
|
||||
else throw new UndeliverableMessageException(e);
|
||||
} catch (EncapsulatedExceptions ee) {
|
||||
Log.w("UniversalTransport", ee);
|
||||
@ -152,6 +154,32 @@ public class UniversalTransport {
|
||||
}
|
||||
}
|
||||
|
||||
private MmsSendResult fallbackOrAskApproval(SendReq mediaMessage, String destination)
|
||||
throws UserInterventionRequiredException, UndeliverableMessageException
|
||||
{
|
||||
boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination);
|
||||
if (!isSmsFallbackApprovalRequired) {
|
||||
Log.i("UniversalTransport", "Falling back to MMS without user intervention");
|
||||
return mmsTransport.deliver(mediaMessage);
|
||||
} else {
|
||||
Log.i("UniversalTransport", "Marking message as pending user approval per their settings");
|
||||
throw new UserInterventionRequiredException("Pending user approval for fallback to SMS");
|
||||
}
|
||||
}
|
||||
|
||||
private void fallbackOrAskApproval(SmsMessageRecord smsMessage, String destination)
|
||||
throws UserInterventionRequiredException, UndeliverableMessageException
|
||||
{
|
||||
boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination);
|
||||
if (!isSmsFallbackApprovalRequired) {
|
||||
Log.i("UniversalTransport", "Falling back to SMS without user intervention");
|
||||
smsTransport.deliver(smsMessage);
|
||||
} else {
|
||||
Log.i("UniversalTransport", "Marking message as pending user approval per their settings");
|
||||
throw new UserInterventionRequiredException("Pending user approval for fallback to SMS");
|
||||
}
|
||||
}
|
||||
|
||||
private MmsSendResult deliverGroupMessage(SendReq mediaMessage, long threadId)
|
||||
throws RetryLaterException, UndeliverableMessageException
|
||||
{
|
||||
@ -209,6 +237,10 @@ public class UniversalTransport {
|
||||
return recipientCount > 1;
|
||||
}
|
||||
|
||||
private boolean isSmsFallbackApprovalRequired(String destination) {
|
||||
return (isSmsFallbackSupported(destination) && TextSecurePreferences.isSmsFallbackAskEnabled(context));
|
||||
}
|
||||
|
||||
private boolean isSmsFallbackSupported(String destination) {
|
||||
if (GroupUtil.isEncodedGroup(destination)) {
|
||||
return false;
|
||||
|
@ -0,0 +1,7 @@
|
||||
package org.thoughtcrime.securesms.transport;
|
||||
|
||||
public class UserInterventionRequiredException extends Exception {
|
||||
public UserInterventionRequiredException(String detailMessage) {
|
||||
super(detailMessage);
|
||||
}
|
||||
}
|
@ -10,8 +10,8 @@ import org.thoughtcrime.securesms.R;
|
||||
|
||||
public class ActionBarUtil {
|
||||
|
||||
public static void initializeDefaultActionBar(final Context c, final ActionBar actionBar, final int title_resid) {
|
||||
actionBar.setTitle(title_resid);
|
||||
public static void initializeDefaultActionBar(final Context c, final ActionBar actionBar, final int titleResId) {
|
||||
actionBar.setTitle(titleResId);
|
||||
initializeDefaultActionBar(c, actionBar);
|
||||
}
|
||||
|
||||
|
@ -45,12 +45,35 @@ public class TextSecurePreferences {
|
||||
private static final String IN_THREAD_NOTIFICATION_PREF = "pref_key_inthread_notifications";
|
||||
|
||||
private static final String LOCAL_REGISTRATION_ID_PREF = "pref_local_registration_id";
|
||||
public static final String ALLOW_SMS_FALLBACK_PREF = "pref_allow_sms_traffic_out";
|
||||
private static final String ALLOW_SMS_FALLBACK_PREF = "pref_allow_sms_traffic_out";
|
||||
private static final String SMS_FALLBACK_ASK_PREF = "pref_sms_fallback_ask";
|
||||
private static final String ALLOW_SMS_NON_DATA_PREF = "pref_sms_non_data_out";
|
||||
|
||||
public static boolean isSmsFallbackEnabled(Context context) {
|
||||
return getBooleanPreference(context, ALLOW_SMS_FALLBACK_PREF, true);
|
||||
}
|
||||
|
||||
public static void setSmsFallbackEnabled(Context context, boolean enabled) {
|
||||
setBooleanPreference(context, ALLOW_SMS_FALLBACK_PREF, enabled);
|
||||
}
|
||||
|
||||
public static boolean isSmsNonDataOutEnabled(Context context) {
|
||||
return getBooleanPreference(context, ALLOW_SMS_NON_DATA_PREF, true);
|
||||
}
|
||||
|
||||
public static void setSmsNonDataOutEnabled(Context context, boolean enabled) {
|
||||
setBooleanPreference(context, ALLOW_SMS_NON_DATA_PREF, enabled);
|
||||
}
|
||||
|
||||
public static boolean isSmsFallbackAskEnabled(Context context) {
|
||||
return getBooleanPreference(context, SMS_FALLBACK_ASK_PREF, false);
|
||||
}
|
||||
|
||||
public static void setSmsFallbackAskEnabled(Context context, boolean enabled) {
|
||||
setBooleanPreference(context, SMS_FALLBACK_ASK_PREF, enabled);
|
||||
}
|
||||
|
||||
|
||||
public static int getLocalRegistrationId(Context context) {
|
||||
return getIntegerPreference(context, LOCAL_REGISTRATION_ID_PREF, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user