From b0216e1494ec596929e72d71032217ac904323e0 Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Mon, 2 Dec 2013 12:31:59 -0800 Subject: [PATCH] Finish KitKat compatibility details. 1) The system does actually enforce having a BROADCAST_SMS permission on the SMS receiver. Break out the "delivered" parts of this into a separate Receiver, so the permission won't trip up GB devices. 2) The system does actually enforce having "quick response" intents. Add a no-op for now. 3) Add a "make default" prompt. 4) Update settings to reflect what's going on in KitKat. --- AndroidManifest.xml | 25 +++++++++++++-- res/values/strings.xml | 7 ++++- res/xml/preferences.xml | 8 +++-- .../ApplicationPreferencesActivity.java | 28 +++++++++++++++++ .../securesms/ConversationListActivity.java | 20 +++++++++++- .../service/QuickResponseService.java | 31 +++++++++++++++++++ .../service/SmsDeliveryListener.java | 21 +++++++++++++ .../securesms/service/SmsListener.java | 20 +++++------- .../securesms/transport/SmsTransport.java | 6 ++-- src/org/thoughtcrime/securesms/util/Util.java | 2 +- 10 files changed, 145 insertions(+), 23 deletions(-) create mode 100644 src/org/thoughtcrime/securesms/service/QuickResponseService.java create mode 100644 src/org/thoughtcrime/securesms/service/SmsDeliveryListener.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index e4720d340b..32804765d3 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -172,6 +172,20 @@ + + + + + + + + + + + + @@ -189,6 +203,7 @@ @@ -197,9 +212,13 @@ - - - + + + + + + Currently unable to send your SMS message. It will be sent once service becomes available. - + + + Sorry, Quick Response is not yet supported by TextSecure! =( + You have received a message from someone who supports TextSecure encrypted sessions. Would you like to initiate a secure session? Initiate Exchange @@ -482,6 +485,8 @@ Theme Default Language + Make Default SMS App + Make TextSecure the default SMS/MMS app for your system. diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index cf4f6668cb..cad3479bbd 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -1,7 +1,7 @@ - + + + - + diff --git a/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java b/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java index 73d96ea142..8ca1c0fbf9 100644 --- a/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java +++ b/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java @@ -22,13 +22,16 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.Preference; +import android.preference.PreferenceGroup; import android.preference.PreferenceManager; import android.preference.PreferenceScreen; import android.provider.ContactsContract; +import android.provider.Telephony; import android.util.Log; import android.widget.Toast; @@ -42,6 +45,7 @@ import org.thoughtcrime.securesms.util.DynamicLanguage; import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.MemoryCleaner; import org.thoughtcrime.securesms.util.Trimmer; +import org.thoughtcrime.securesms.util.Util; /** * The Activity for application preference display and management. @@ -65,7 +69,9 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr public static final String LED_BLINK_PREF = "pref_led_blink"; public static final String LED_BLINK_PREF_CUSTOM = "pref_led_blink_custom"; public static final String IDENTITY_PREF = "pref_choose_identity"; + public static final String ALL_SMS_PREF = "pref_all_sms"; public static final String ALL_MMS_PERF = "pref_all_mms"; + public static final String KITKAT_DEFAULT_PREF = "pref_set_default"; public static final String PASSPHRASE_TIMEOUT_INTERVAL_PREF = "pref_timeout_interval"; public static final String PASSPHRASE_TIMEOUT_PREF = "pref_timeout_passphrase"; public static final String AUTO_KEY_EXCHANGE_PREF = "pref_auto_complete_key_exchange"; @@ -110,6 +116,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr addPreferencesFromResource(R.xml.preferences); initializeIdentitySelection(); + initializePlatformSpecificOptions(); this.findPreference(CHANGE_PASSPHRASE_PREF) .setOnPreferenceClickListener(new ChangePassphraseClickListener()); @@ -176,6 +183,27 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr return false; } + private void initializePlatformSpecificOptions() { + PreferenceGroup generalCategory = (PreferenceGroup)findPreference("general_category"); + Preference defaultPreference = findPreference(KITKAT_DEFAULT_PREF); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + generalCategory.removePreference(findPreference(ALL_SMS_PREF)); + generalCategory.removePreference(findPreference(ALL_MMS_PERF)); + + if (Util.isDefaultSmsProvider(this)) { + generalCategory.removePreference(defaultPreference); + } else { + Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT); + intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, getPackageName()); + + defaultPreference.setIntent(intent); + } + } else { + generalCategory.removePreference(defaultPreference); + } + } + private void initializeIdentitySelection() { ContactIdentityManager identity = ContactIdentityManager.getInstance(this); diff --git a/src/org/thoughtcrime/securesms/ConversationListActivity.java b/src/org/thoughtcrime/securesms/ConversationListActivity.java index 45166143f3..ef7f3056c6 100644 --- a/src/org/thoughtcrime/securesms/ConversationListActivity.java +++ b/src/org/thoughtcrime/securesms/ConversationListActivity.java @@ -6,7 +6,9 @@ import android.database.ContentObserver; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.preference.PreferenceManager; import android.provider.ContactsContract; +import android.provider.Telephony; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.util.Log; @@ -19,7 +21,7 @@ import android.widget.SimpleAdapter; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; -import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; + import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.ThreadDatabase; @@ -31,6 +33,7 @@ import org.thoughtcrime.securesms.service.SendReceiveService; import org.thoughtcrime.securesms.util.DynamicLanguage; import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.MemoryCleaner; +import org.thoughtcrime.securesms.util.Util; import java.util.ArrayList; import java.util.HashMap; @@ -68,6 +71,8 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment super.onResume(); dynamicTheme.onResume(this); dynamicLanguage.onResume(this); + + initializeDefaultMessengerCheck(); } @Override @@ -254,4 +259,17 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment this.fragment.setMasterSecret(masterSecret); } + private void initializeDefaultMessengerCheck() { + if (!Util.isDefaultSmsProvider(this) && + !(PreferenceManager.getDefaultSharedPreferences(this) + .getBoolean("pref_prompted_default_sms", false))) + { + PreferenceManager.getDefaultSharedPreferences(this).edit() + .putBoolean("pref_prompted_default_sms", true).commit(); + Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT); + intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, getPackageName()); + startActivity(intent); + } } + +} diff --git a/src/org/thoughtcrime/securesms/service/QuickResponseService.java b/src/org/thoughtcrime/securesms/service/QuickResponseService.java new file mode 100644 index 0000000000..b37ed0aeb3 --- /dev/null +++ b/src/org/thoughtcrime/securesms/service/QuickResponseService.java @@ -0,0 +1,31 @@ +package org.thoughtcrime.securesms.service; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.telephony.TelephonyManager; +import android.util.Log; +import android.widget.Toast; + +import org.thoughtcrime.securesms.R; + +public class QuickResponseService extends Service { + + public int onStartCommand(Intent intent, int flags, int startId) { + if (!TelephonyManager.ACTION_RESPOND_VIA_MESSAGE.equals(intent.getAction())) { + Log.w("QuickResponseService", "Received unknown intent: " + intent.getAction()); + return START_NOT_STICKY; + } + + Toast.makeText(this, + getString(R.string.QuickResponseService_sorry_quick_response_is_not_yet_supported_by_textsecure), + Toast.LENGTH_LONG).show(); + + return START_NOT_STICKY; + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } +} diff --git a/src/org/thoughtcrime/securesms/service/SmsDeliveryListener.java b/src/org/thoughtcrime/securesms/service/SmsDeliveryListener.java new file mode 100644 index 0000000000..2931639bd5 --- /dev/null +++ b/src/org/thoughtcrime/securesms/service/SmsDeliveryListener.java @@ -0,0 +1,21 @@ +package org.thoughtcrime.securesms.service; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +public class SmsDeliveryListener extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + if (SendReceiveService.SENT_SMS_ACTION.equals(intent.getAction())) { + intent.putExtra("ResultCode", this.getResultCode()); + intent.setClass(context, SendReceiveService.class); + context.startService(intent); + } else if (SendReceiveService.DELIVERED_SMS_ACTION.equals(intent.getAction())) { + intent.putExtra("ResultCode", this.getResultCode()); + intent.setClass(context, SendReceiveService.class); + context.startService(intent); + } + } +} diff --git a/src/org/thoughtcrime/securesms/service/SmsListener.java b/src/org/thoughtcrime/securesms/service/SmsListener.java index fb06444409..b9392bba0e 100644 --- a/src/org/thoughtcrime/securesms/service/SmsListener.java +++ b/src/org/thoughtcrime/securesms/service/SmsListener.java @@ -106,8 +106,11 @@ public class SmsListener extends BroadcastReceiver { intent.getAction().equals(SMS_RECEIVED_ACTION) && Util.isDefaultSmsProvider(context)) return false; - if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("pref_all_sms", true)) + if (PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(ApplicationPreferencesActivity.ALL_SMS_PREF, true)) + { return true; + } return WirePrefix.isEncryptedMessage(messageBody) || WirePrefix.isKeyExchange(messageBody); } @@ -140,7 +143,7 @@ public class SmsListener extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Log.w("SMSListener", "Got SMS broadcast..."); - if (intent.getAction().equals(SMS_RECEIVED_ACTION) && isChallenge(context, intent)) { + if (SMS_RECEIVED_ACTION.equals(intent.getAction()) && isChallenge(context, intent)) { Log.w("SmsListener", "Got challenge!"); Intent challengeIntent = new Intent(RegistrationService.CHALLENGE_EVENT); challengeIntent.putExtra(RegistrationService.CHALLENGE_EXTRA, parseChallenge(context, intent)); @@ -148,8 +151,9 @@ public class SmsListener extends BroadcastReceiver { abortBroadcast(); } else if ((intent.getAction().equals(SMS_RECEIVED_ACTION) || - intent.getAction().equals(SMS_DELIVERED_ACTION)) && - isRelevant(context, intent)) { + intent.getAction().equals(SMS_DELIVERED_ACTION)) && + isRelevant(context, intent)) + { Intent receivedIntent = new Intent(context, SendReceiveService.class); receivedIntent.setAction(SendReceiveService.RECEIVE_SMS_ACTION); receivedIntent.putExtra("ResultCode", this.getResultCode()); @@ -157,14 +161,6 @@ public class SmsListener extends BroadcastReceiver { context.startService(receivedIntent); abortBroadcast(); - } else if (intent.getAction().equals(SendReceiveService.SENT_SMS_ACTION)) { - intent.putExtra("ResultCode", this.getResultCode()); - intent.setClass(context, SendReceiveService.class); - context.startService(intent); - } else if (intent.getAction().equals(SendReceiveService.DELIVERED_SMS_ACTION)) { - intent.putExtra("ResultCode", this.getResultCode()); - intent.setClass(context, SendReceiveService.class); - context.startService(intent); } } } diff --git a/src/org/thoughtcrime/securesms/transport/SmsTransport.java b/src/org/thoughtcrime/securesms/transport/SmsTransport.java index e0b068b2e1..7ba1fd3bc0 100644 --- a/src/org/thoughtcrime/securesms/transport/SmsTransport.java +++ b/src/org/thoughtcrime/securesms/transport/SmsTransport.java @@ -14,7 +14,7 @@ import org.thoughtcrime.securesms.crypto.SessionCipher; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.service.SendReceiveService; -import org.thoughtcrime.securesms.service.SmsListener; +import org.thoughtcrime.securesms.service.SmsDeliveryListener; import org.thoughtcrime.securesms.sms.MultipartSmsMessageHandler; import org.thoughtcrime.securesms.sms.OutgoingTextMessage; import org.thoughtcrime.securesms.sms.SmsTransportDetails; @@ -109,7 +109,7 @@ public class SmsTransport { ArrayList sentIntents = new ArrayList(messages.size()); for (int i=0;i deliveredIntents = new ArrayList(messages.size()); for (int i=0;i