move routing logic to all activities

Fixes #2239
Closes #27923

// FREEBIE
master
Jake McGinty 2014-12-15 12:25:55 -08:00 committed by Moxie Marlinspike
parent 141ee6565d
commit 0ff99258ac
52 changed files with 503 additions and 984 deletions

View File

@ -9,7 +9,7 @@
android:label="Access to TextSecure Secrets"
android:protectionLevel="signature" />
<uses-permission android:name="org.thoughtcrime.securesms.ACCESS_SECRETS"/>
<uses-permission android:name="org.thoughtcrime.securesms.ACCESS_SECRETS"/>
<uses-permission android:name="android.permission.READ_PROFILE"/>
<uses-permission android:name="android.permission.WRITE_PROFILE"/>
<uses-permission android:name="android.permission.BROADCAST_WAP_PUSH"
@ -42,38 +42,8 @@
android:label="@string/app_name"
android:theme="@style/TextSecure.LightTheme">
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity android:name=".RoutingActivity"
android:theme="@style/NoAnimation.Theme.BlackScreen"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SENDTO"/>
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="audio/*" />
<data android:mimeType="image/*" />
<data android:mimeType="text/plain" />
<data android:mimeType="video/*" />
</intent-filter>
</activity>
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity android:name=".RegistrationProblemsActivity"
android:theme="@style/TextSecure.Light.Dialog"
@ -109,17 +79,35 @@
android:launchMode="singleTask"
android:noHistory="true"
android:windowSoftInputMode="stateHidden"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="audio/*" />
<data android:mimeType="image/*" />
<data android:mimeType="text/plain" />
<data android:mimeType="video/*" />
</intent-filter>
</activity>
<activity android:name=".ConversationListActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ConversationActivity"
android:windowSoftInputMode="stateUnchanged"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize" />
<activity android:name=".MessageDetailsActivity"
android:label="Message Details"
@ -145,12 +133,12 @@
android:label="@string/AndroidManifest__create_passphrase"
android:windowSoftInputMode="stateUnchanged"
android:theme="@style/TextSecure.IntroTheme"
android:launchMode="singleTop"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".PassphrasePromptActivity"
android:label="@string/AndroidManifest__enter_passphrase"
android:launchMode="singleTop"
android:launchMode="singleTask"
android:theme="@style/TextSecure.IntroTheme"
android:windowSoftInputMode="stateAlwaysVisible"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
@ -224,6 +212,17 @@
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".SmsSendtoActivity">
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</activity>
<activity android:name="com.soundcloud.android.crop.CropImageActivity" />
<service android:enabled="true" android:name=".service.ApplicationMigrationService"/>
@ -245,14 +244,6 @@
</service>
<!-- <receiver android:name=".service.BootListener" -->
<!-- android:enabled="true" -->
<!-- android:exported="false">-->
<!-- <intent-filter>-->
<!-- <action android:name="android.intent.action.BOOT_COMPLETED" />-->
<!-- </intent-filter>-->
<!-- </receiver>-->
<receiver android:name=".gcm.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />

View File

@ -14,12 +14,10 @@
android:orientation="vertical"
android:gravity="bottom">
<fragment
android:id="@+id/fragment_content"
android:name="org.thoughtcrime.securesms.ConversationFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bottom_container" />
<FrameLayout android:id="@+id/fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bottom_container" />
<LinearLayout
android:layout_alignParentBottom="true"

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/fragment_content"
android:name="org.thoughtcrime.securesms.ConversationListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="@layout/conversation_list_fragment" />
</LinearLayout>

View File

@ -1,13 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:id="@+id/fragment_content"
android:name="org.thoughtcrime.securesms.ShareFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</FrameLayout>

View File

@ -115,6 +115,7 @@
<string name="ConversationActivity_error_leaving_group">Error leaving group...</string>
<string name="ConversationActivity_mms_not_supported_title">MMS not supported</string>
<string name="ConversationActivity_mms_not_supported_message">This message cannot be sent since your carrier doesn\'t support MMS.</string>
<string name="ConversationActivity_specify_recipient">Please choose a contact</string>
<!-- ConversationFragment -->
<string name="ConversationFragment_message_details">Message details</string>

View File

@ -1,36 +0,0 @@
package org.thoughtcrime.securesms;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.HeaderViewListAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
public abstract class ActionBarListActivity extends ActionBarActivity {
private ListView mListView;
protected ListView getListView() {
if (mListView == null) {
mListView = (ListView) findViewById(android.R.id.list);
}
return mListView;
}
protected void setListAdapter(ListAdapter adapter) {
getListView().setAdapter(adapter);
}
protected ListAdapter getListAdapter() {
ListAdapter adapter = getListView().getAdapter();
if (adapter instanceof HeaderViewListAdapter) {
return ((HeaderViewListAdapter)adapter).getWrappedAdapter();
} else {
return adapter;
}
}
protected void onListItemClick(ListView lv, View v, int position, long id) {
getListView().getOnItemClickListener().onItemClick(lv, v, position, id);
}
}

View File

@ -20,6 +20,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.Preference;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
@ -35,7 +36,6 @@ import org.thoughtcrime.securesms.preferences.StoragePreferenceFragment;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.MemoryCleaner;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
/**
@ -61,18 +61,24 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
@Override
protected void onCreate(Bundle icicle) {
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
super.onCreate(icicle);
}
@Override
protected void onCreate(Bundle icicle, @NonNull MasterSecret masterSecret) {
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Fragment fragment = new ApplicationPreferenceFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(android.R.id.content, fragment);
fragmentTransaction.commit();
Bundle fragmentArgs = new Bundle();
Fragment fragment = new ApplicationPreferenceFragment();
fragmentArgs.putParcelable("master_secret", masterSecret);
fragment.setArguments(fragmentArgs);
getSupportFragmentManager().beginTransaction()
.replace(android.R.id.content, fragment)
.commit();
}
@Override
@ -104,12 +110,6 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
return true;
}
@Override
public void onDestroy() {
MemoryCleaner.clean((MasterSecret) getIntent().getParcelableExtra("master_secret"));
super.onDestroy();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(TextSecurePreferences.THEME_PREF)) {
@ -129,18 +129,19 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
super.onCreate(icicle);
addPreferencesFromResource(R.xml.preferences);
MasterSecret masterSecret = getArguments().getParcelable("master_secret");
this.findPreference(PREFERENCE_CATEGORY_SMS_MMS)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_SMS_MMS));
.setOnPreferenceClickListener(new CategoryClickListener(masterSecret, PREFERENCE_CATEGORY_SMS_MMS));
this.findPreference(PREFERENCE_CATEGORY_NOTIFICATIONS)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_NOTIFICATIONS));
.setOnPreferenceClickListener(new CategoryClickListener(masterSecret, PREFERENCE_CATEGORY_NOTIFICATIONS));
this.findPreference(PREFERENCE_CATEGORY_APP_PROTECTION)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_APP_PROTECTION));
.setOnPreferenceClickListener(new CategoryClickListener(masterSecret, PREFERENCE_CATEGORY_APP_PROTECTION));
this.findPreference(PREFERENCE_CATEGORY_APPEARANCE)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_APPEARANCE));
.setOnPreferenceClickListener(new CategoryClickListener(masterSecret, PREFERENCE_CATEGORY_APPEARANCE));
this.findPreference(PREFERENCE_CATEGORY_STORAGE)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_STORAGE));
.setOnPreferenceClickListener(new CategoryClickListener(masterSecret, PREFERENCE_CATEGORY_STORAGE));
this.findPreference(PREFERENCE_CATEGORY_ADVANCED)
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_ADVANCED));
.setOnPreferenceClickListener(new CategoryClickListener(masterSecret, PREFERENCE_CATEGORY_ADVANCED));
}
@Override
@ -164,10 +165,12 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
}
private class CategoryClickListener implements Preference.OnPreferenceClickListener {
private String category;
private MasterSecret masterSecret;
private String category;
public CategoryClickListener(String category) {
this.category = category;
public CategoryClickListener(MasterSecret masterSecret, String category) {
this.masterSecret = masterSecret;
this.category = category;
}
@Override
@ -182,7 +185,10 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
fragment = new NotificationsPreferenceFragment();
break;
case PREFERENCE_CATEGORY_APP_PROTECTION:
Bundle args = new Bundle();
args.putParcelable("master_secret", masterSecret);
fragment = new AppProtectionPreferenceFragment();
fragment.setArguments(args);
break;
case PREFERENCE_CATEGORY_APPEARANCE:
fragment = new AppearancePreferenceFragment();

View File

@ -27,6 +27,7 @@ import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.telephony.PhoneNumberUtils;
import android.text.Editable;
import android.text.InputType;
@ -94,7 +95,6 @@ import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.Emoji;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.util.MemoryCleaner;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.libaxolotl.InvalidMessageException;
@ -126,7 +126,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
public static final String RECIPIENTS_EXTRA = "recipients";
public static final String THREAD_ID_EXTRA = "thread_id";
public static final String MASTER_SECRET_EXTRA = "master_secret";
public static final String DRAFT_TEXT_EXTRA = "draft_text";
public static final String DRAFT_IMAGE_EXTRA = "draft_image";
public static final String DRAFT_AUDIO_EXTRA = "draft_audio";
@ -139,10 +138,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private static final int PICK_CONTACT_INFO = 4;
private static final int GROUP_EDIT = 5;
private MasterSecret masterSecret;
private ComposeText composeText;
private SendButton sendButton;
private TextView charactersLeft;
private MasterSecret masterSecret;
private ComposeText composeText;
private SendButton sendButton;
private TextView charactersLeft;
private ConversationFragment fragment;
private AttachmentTypeSelectorAdapter attachmentAdapter;
private AttachmentManager attachmentManager;
@ -161,14 +161,19 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private DynamicLanguage dynamicLanguage = new DynamicLanguage();
@Override
protected void onCreate(Bundle state) {
overridePendingTransition(R.anim.slide_from_right, R.anim.fade_scale_out);
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
super.onCreate(state);
overridePendingTransition(R.anim.slide_from_right, R.anim.fade_scale_out);
}
@Override
protected void onCreate(Bundle state, @NonNull MasterSecret masterSecret) {
this.masterSecret = masterSecret;
setContentView(R.layout.conversation_activity);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
fragment = initFragment(R.id.fragment_content, new ConversationFragment(), masterSecret);
initializeReceivers();
initializeViews();
@ -178,6 +183,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
@Override
protected void onNewIntent(Intent intent) {
Log.w(TAG, "onNewIntent()");
if (!Util.isEmpty(composeText) || attachmentManager.isAttachmentPresent()) {
saveDraft();
attachmentManager.clear();
@ -185,12 +192,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
setIntent(intent);
initializeResources();
initializeDraft();
ConversationFragment fragment = getFragment();
if (fragment != null) {
fragment.onNewIntent();
}
@ -223,10 +227,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
@Override
protected void onDestroy() {
saveDraft();
recipients.removeListener(this);
unregisterReceiver(securityUpdateReceiver);
unregisterReceiver(groupUpdateReceiver);
MemoryCleaner.clean(masterSecret);
if (recipients != null) recipients.removeListener(this);
if (securityUpdateReceiver != null) unregisterReceiver(securityUpdateReceiver);
if (groupUpdateReceiver != null) unregisterReceiver(groupUpdateReceiver);
super.onDestroy();
}
@ -333,7 +336,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private void handleReturnToConversationList() {
Intent intent = new Intent(this, ConversationListActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("master_secret", masterSecret);
startActivity(intent);
finish();
}
@ -351,7 +353,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private void handleVerifyIdentity() {
Intent verifyIdentityIntent = new Intent(this, VerifyIdentityActivity.class);
verifyIdentityIntent.putExtra("recipient", getRecipients().getPrimaryRecipient().getRecipientId());
verifyIdentityIntent.putExtra("master_secret", masterSecret);
startActivity(verifyIdentityIntent);
}
@ -392,7 +393,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
Intent intent = new Intent(this, MediaOverviewActivity.class);
intent.putExtra(MediaOverviewActivity.THREAD_ID_EXTRA, threadId);
intent.putExtra(MediaOverviewActivity.RECIPIENT_EXTRA, recipients.getPrimaryRecipient().getRecipientId());
intent.putExtra(MediaOverviewActivity.MASTER_SECRET_EXTRA, masterSecret);
startActivity(intent);
}
@ -439,7 +439,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private void handleEditPushGroup() {
Intent intent = new Intent(ConversationActivity.this, GroupCreateActivity.class);
intent.putExtra(GroupCreateActivity.MASTER_SECRET_EXTRA, masterSecret);
intent.putExtra(GroupCreateActivity.GROUP_RECIPIENT_EXTRA, recipients.getPrimaryRecipient().getRecipientId());
startActivityForResult(intent, GROUP_EDIT);
}
@ -724,7 +723,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
recipients = RecipientFactory.getRecipientsForIds(this, getIntent().getLongArrayExtra(RECIPIENTS_EXTRA), true);
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
distributionType = getIntent().getIntExtra(DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
masterSecret = getIntent().getParcelableExtra(MASTER_SECRET_EXTRA);
recipients.addListener(this);
}
@ -901,8 +899,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} else if (threadId > 0) {
threadDatabase.update(threadId);
}
MemoryCleaner.clean(thisMasterSecret);
return null;
}
}.execute(thisThreadId);
@ -978,8 +974,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
boolean refreshFragment = (threadId != this.threadId);
this.threadId = threadId;
ConversationFragment fragment = getFragment();
if (fragment == null) {
return;
}
@ -994,10 +988,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
fragment.scrollToBottom();
}
private ConversationFragment getFragment() {
return (ConversationFragment)getSupportFragmentManager().findFragmentById(R.id.fragment_content);
}
private void sendMessage() {
try {
Recipients recipients = getRecipients();

View File

@ -61,6 +61,12 @@ public class ConversationFragment extends ListFragment
private long threadId;
private ActionMode actionMode;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
this.masterSecret = getArguments().getParcelable("master_secret");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
return inflater.inflate(R.layout.conversation_fragment, container, false);
@ -101,7 +107,6 @@ public class ConversationFragment extends ListFragment
}
private void initializeResources() {
this.masterSecret = this.getActivity().getIntent().getParcelableExtra("master_secret");
this.recipients = RecipientFactory.getRecipientsForIds(getActivity(), getActivity().getIntent().getLongArrayExtra("recipients"), true);
this.threadId = this.getActivity().getIntent().getLongExtra("thread_id", -1);
}
@ -233,7 +238,6 @@ public class ConversationFragment extends ListFragment
private void handleForwardMessage(MessageRecord message) {
Intent composeIntent = new Intent(getActivity(), ShareActivity.class);
composeIntent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, message.getDisplayBody().toString());
composeIntent.putExtra(ShareActivity.MASTER_SECRET_EXTRA, masterSecret);
startActivity(composeIntent);
}

View File

@ -426,7 +426,6 @@ public class ConversationItem extends LinearLayout {
intent.putExtra("is_bundle", messageRecord.isBundleKeyExchange());
intent.putExtra("is_identity_update", messageRecord.isIdentityUpdate());
intent.putExtra("is_push", messageRecord.isPush());
intent.putExtra("master_secret", masterSecret);
intent.putExtra("sent", messageRecord.isOutgoing());
context.startActivity(intent);
}
@ -458,7 +457,6 @@ public class ConversationItem extends LinearLayout {
Intent intent = new Intent(context, MediaPreviewActivity.class);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(slide.getUri(), slide.getContentType());
intent.putExtra(MediaPreviewActivity.MASTER_SECRET_EXTRA, masterSecret);
if (!messageRecord.isOutgoing()) intent.putExtra(MediaPreviewActivity.RECIPIENT_EXTRA, messageRecord.getIndividualRecipient().getRecipientId());
intent.putExtra(MediaPreviewActivity.DATE_EXTRA, messageRecord.getDateReceived());

View File

@ -21,6 +21,7 @@ import android.database.ContentObserver;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar;
import android.util.Log;
import android.support.v4.view.MenuItemCompat;
@ -38,41 +39,36 @@ import org.thoughtcrime.securesms.service.DirectoryRefreshListener;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.MemoryCleaner;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
public class ConversationListActivity extends PassphraseRequiredActionBarActivity
implements ConversationListFragment.ConversationSelectedListener
{
{
private final DynamicTheme dynamicTheme = new DynamicTheme ();
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
private ConversationListFragment fragment;
private MasterSecret masterSecret;
private ContentObserver observer;
private MasterSecret masterSecret;
@Override
public void onCreate(Bundle icicle) {
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
super.onCreate(icicle);
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
setContentView(R.layout.conversation_list_activity);
getSupportActionBar().setTitle(R.string.app_name);
initializeResources();
initializeContactUpdatesReceiver();
DirectoryRefreshListener.schedule(this);
}
@Override
public void onPostCreate(Bundle bundle) {
super.onPostCreate(bundle);
protected void onCreate(Bundle icicle, @NonNull MasterSecret masterSecret) {
this.masterSecret = masterSecret;
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
getSupportActionBar().setTitle(R.string.app_name);
fragment = initFragment(android.R.id.content, new ConversationListFragment(), masterSecret);
initializeContactUpdatesReceiver();
DirectoryRefreshListener.schedule(this);
}
@Override
@ -84,19 +80,10 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
@Override
public void onDestroy() {
Log.w("ConversationListActivity", "onDestroy...");
MemoryCleaner.clean(masterSecret);
if (observer != null) getContentResolver().unregisterContentObserver(observer);
super.onDestroy();
}
@Override
public void onMasterSecretCleared() {
// this.fragment.setMasterSecret(null);
startActivity(new Intent(this, RoutingActivity.class));
super.onMasterSecretCleared();
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuInflater inflater = this.getMenuInflater();
@ -106,13 +93,9 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
menu.findItem(R.id.menu_clear_passphrase).setVisible(!TextSecurePreferences.isPasswordDisabled(this));
if (this.masterSecret != null) {
inflater.inflate(R.menu.conversation_list, menu);
MenuItem menuItem = menu.findItem(R.id.menu_search);
initializeSearch(menuItem);
} else {
inflater.inflate(R.menu.conversation_list_empty, menu);
}
inflater.inflate(R.menu.conversation_list, menu);
MenuItem menuItem = menu.findItem(R.id.menu_search);
initializeSearch(menuItem);
super.onPrepareOptionsMenu(menu);
return true;
@ -177,7 +160,6 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
private void createGroup() {
Intent intent = new Intent(this, GroupCreateActivity.class);
intent.putExtra("master_secret", masterSecret);
startActivity(intent);
}
@ -185,7 +167,6 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
Intent intent = new Intent(this, ConversationActivity.class);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.getIds());
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
intent.putExtra(ConversationActivity.MASTER_SECRET_EXTRA, masterSecret);
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, distributionType);
startActivity(intent);
@ -193,7 +174,6 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
private void handleDisplaySettings() {
Intent preferencesIntent = new Intent(this, ApplicationPreferencesActivity.class);
preferencesIntent.putExtra("master_secret", masterSecret);
startActivity(preferencesIntent);
}
@ -204,15 +184,11 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
}
private void handleImportExport() {
final Intent intent = new Intent(this, ImportExportActivity.class);
intent.putExtra("master_secret", masterSecret);
startActivity(intent);
startActivity(new Intent(this, ImportExportActivity.class));
}
private void handleMyIdentity() {
final Intent intent = new Intent(this, ViewLocalIdentityActivity.class);
intent.putExtra("master_secret", masterSecret);
startActivity(intent);
startActivity(new Intent(this, ViewLocalIdentityActivity.class));
}
private void handleMarkAllRead() {
@ -237,8 +213,8 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
ConversationListActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
((ConversationListAdapter)fragment.getListAdapter()).notifyDataSetChanged();
}
((ConversationListAdapter)fragment.getListAdapter()).notifyDataSetChanged();
}
});
}
};
@ -246,13 +222,4 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI,
true, observer);
}
private void initializeResources() {
this.masterSecret = getIntent().getParcelableExtra("master_secret");
this.fragment = (ConversationListFragment)this.getSupportFragmentManager()
.findFragmentById(R.id.fragment_content);
this.fragment.setMasterSecret(masterSecret);
}
}

View File

@ -61,13 +61,18 @@ public class ConversationListFragment extends ListFragment
implements LoaderManager.LoaderCallbacks<Cursor>, ActionMode.Callback
{
private ConversationSelectedListener listener;
private MasterSecret masterSecret;
private ActionMode actionMode;
private ReminderView reminderView;
private FloatingActionButton fab;
private String queryFilter = "";
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
masterSecret = getArguments().getParcelable("master_secret");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
final View view = inflater.inflate(R.layout.conversation_list_fragment, container, false);
@ -76,12 +81,6 @@ public class ConversationListFragment extends ListFragment
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
getListView().setAdapter(null);
}
@Override
public void onActivityCreated(Bundle bundle) {
super.onActivityCreated(bundle);
@ -92,9 +91,7 @@ public class ConversationListFragment extends ListFragment
fab.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), NewConversationActivity.class);
intent.putExtra(NewConversationActivity.MASTER_SECRET_EXTRA, masterSecret);
startActivity(intent);
startActivity(new Intent(getActivity(), NewConversationActivity.class));
}
});
initializeListAdapter();
@ -111,12 +108,6 @@ public class ConversationListFragment extends ListFragment
((ConversationListAdapter)getListAdapter()).notifyDataSetChanged();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.listener = (ConversationSelectedListener)activity;
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
if (v instanceof ConversationListItem) {
@ -140,13 +131,6 @@ public class ConversationListFragment extends ListFragment
}
}
public void setMasterSecret(MasterSecret masterSecret) {
if (this.masterSecret != masterSecret) {
this.masterSecret = masterSecret;
initializeListAdapter();
}
}
public void setQueryFilter(String query) {
this.queryFilter = query;
getLoaderManager().restartLoader(0, null, this);
@ -250,7 +234,7 @@ public class ConversationListFragment extends ListFragment
}
private void handleCreateConversation(long threadId, Recipients recipients, int distributionType) {
listener.onCreateConversation(threadId, recipients, distributionType);
((ConversationSelectedListener)getActivity()).onCreateConversation(threadId, recipients, distributionType);
}
@Override

View File

@ -10,12 +10,14 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.NonNull;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.SmsMigrator.ProgressDescription;
import org.thoughtcrime.securesms.service.ApplicationMigrationService;
import org.thoughtcrime.securesms.service.ApplicationMigrationService.ImportState;
@ -37,8 +39,7 @@ public class DatabaseMigrationActivity extends PassphraseRequiredActionBarActivi
private boolean isVisible = false;
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
protected void onCreate(Bundle bundle, @NonNull MasterSecret masterSecret) {
setContentView(R.layout.database_migration_activity);
initializeResources();

View File

@ -5,6 +5,7 @@ import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.util.Log;
@ -40,9 +41,13 @@ public class DeviceProvisioningActivity extends PassphraseRequiredActionBarActiv
private MasterSecret masterSecret;
@Override
public void onCreate(Bundle bundle) {
protected void onPreCreate() {
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(bundle);
}
@Override
protected void onCreate(Bundle bundle, @NonNull MasterSecret masterSecret) {
this.masterSecret = masterSecret;
getSupportActionBar().hide();
initializeResources();
@ -80,11 +85,6 @@ public class DeviceProvisioningActivity extends PassphraseRequiredActionBarActiv
.show();
}
@Override
public void onNewMasterSecret(MasterSecret masterSecret) {
this.masterSecret = masterSecret;
}
private void initializeResources() {
this.uri = getIntent().getData();
}

View File

@ -25,6 +25,7 @@ import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
@ -51,7 +52,6 @@ import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.util.BitmapDecodingException;
@ -70,7 +70,6 @@ import org.whispersystems.textsecure.api.util.InvalidNumberException;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@ -95,7 +94,6 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
public static final String GROUP_RECIPIENT_EXTRA = "group_recipient";
public static final String GROUP_THREAD_EXTRA = "group_thread";
public static final String MASTER_SECRET_EXTRA = "master_secret";
private final DynamicTheme dynamicTheme = new DynamicTheme();
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
@ -117,20 +115,24 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
private String existingTitle = null;
private Bitmap existingAvatarBmp = null;
private MasterSecret masterSecret;
private Bitmap avatarBmp;
private MasterSecret masterSecret;
private Bitmap avatarBmp;
private Set<Recipient> selectedContacts;
@Override
public void onCreate(Bundle state) {
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
super.onCreate(state);
}
@Override
protected void onCreate(Bundle state, @NonNull MasterSecret masterSecret) {
this.masterSecret = masterSecret;
setContentView(R.layout.group_create_activity);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
selectedContacts = new HashSet<Recipient>();
selectedContacts = new HashSet<>();
initializeResources();
}
@ -234,8 +236,6 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
}
}
masterSecret = getIntent().getParcelableExtra(MASTER_SECRET_EXTRA);
lv = (ListView) findViewById(R.id.selected_contacts_list);
avatar = (ImageView) findViewById(R.id.avatar);
groupName = (EditText) findViewById(R.id.group_name);
@ -531,7 +531,6 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
protected void onPostExecute(Long resultThread) {
if (resultThread > -1) {
Intent intent = new Intent(GroupCreateActivity.this, ConversationActivity.class);
intent.putExtra(ConversationActivity.MASTER_SECRET_EXTRA, masterSecret);
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, resultThread.longValue());
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
@ -632,7 +631,6 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
final Recipients recipients = groupInfo.second;
if (threadId > -1) {
Intent intent = new Intent(GroupCreateActivity.this, ConversationActivity.class);
intent.putExtra(ConversationActivity.MASTER_SECRET_EXTRA, masterSecret);
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.getIds());

View File

@ -114,7 +114,6 @@ public class ImageMediaAdapter extends CursorRecyclerViewAdapter<ViewHolder> {
@Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), MediaPreviewActivity.class);
intent.putExtra(MediaPreviewActivity.MASTER_SECRET_EXTRA, masterSecret);
intent.putExtra(MediaPreviewActivity.DATE_EXTRA, record.getDate());
if (!TextUtils.isEmpty(record.getAddress())) {

View File

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
@ -15,16 +16,20 @@ import org.thoughtcrime.securesms.util.DynamicTheme;
public class ImportExportActivity extends PassphraseRequiredActionBarActivity {
private MasterSecret masterSecret;
private TabPagerAdapter tabPagerAdapter;
private ViewPager viewPager;
private MasterSecret masterSecret;
private ViewPager viewPager;
private DynamicTheme dynamicTheme = new DynamicTheme();
@Override
public void onCreate(Bundle savedInstanceState) {
protected void onPreCreate() {
dynamicTheme.onCreate(this);
super.onCreate(savedInstanceState);
}
@Override
protected void onCreate(Bundle savedInstanceState, @NonNull MasterSecret masterSecret) {
this.masterSecret = masterSecret;
setContentView(R.layout.import_export_activity);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
@ -51,7 +56,6 @@ public class ImportExportActivity extends PassphraseRequiredActionBarActivity {
}
private void initializeResources() {
this.masterSecret = getIntent().getParcelableExtra("master_secret");
this.viewPager = (ViewPager) findViewById(R.id.import_export_pager);
this.tabPagerAdapter = new TabPagerAdapter(getSupportFragmentManager());
@ -116,4 +120,4 @@ public class ImportExportActivity extends PassphraseRequiredActionBarActivity {
}
}
}
}

View File

@ -95,10 +95,8 @@ public class ImportFragment extends Fragment {
getActivity().startService(intent);
Intent nextIntent = new Intent(getActivity(), ConversationListActivity.class);
intent.putExtra("master_secret", masterSecret);
Intent activityIntent = new Intent(getActivity(), DatabaseMigrationActivity.class);
activityIntent.putExtra("master_secret", masterSecret);
activityIntent.putExtra("next_intent", nextIntent);
getActivity().startActivity(activityIntent);
}

View File

@ -26,6 +26,7 @@ import android.widget.Toast;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.Dialogs;
import org.thoughtcrime.securesms.util.DynamicLanguage;
@ -43,10 +44,9 @@ public abstract class KeyScanningActivity extends PassphraseRequiredActionBarAct
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
@Override
protected void onCreate(Bundle bundle) {
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
super.onCreate(bundle);
}
@Override

View File

@ -0,0 +1,5 @@
package org.thoughtcrime.securesms;
public interface MasterSecretListener {
void onMasterSecretCleared();
}

View File

@ -23,6 +23,7 @@ import android.database.Cursor;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.widget.GridLayoutManager;
@ -48,9 +49,8 @@ import org.thoughtcrime.securesms.util.DynamicLanguage;
public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity implements LoaderManager.LoaderCallbacks<Cursor> {
private final static String TAG = MediaOverviewActivity.class.getSimpleName();
public final static String MASTER_SECRET_EXTRA = "master_secret";
public final static String RECIPIENT_EXTRA = "recipient";
public final static String THREAD_ID_EXTRA = "thread_id";
public static final String RECIPIENT_EXTRA = "recipient";
public static final String THREAD_ID_EXTRA = "thread_id";
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
@ -63,11 +63,14 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity i
private long threadId;
@Override
protected void onCreate(Bundle bundle) {
protected void onPreCreate() {
this.setTheme(R.style.TextSecure_DarkTheme);
dynamicLanguage.onCreate(this);
}
super.onCreate(bundle);
@Override
protected void onCreate(Bundle bundle, @NonNull MasterSecret masterSecret) {
this.masterSecret = masterSecret;
setFullscreenIfPossible();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
@ -112,8 +115,7 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity i
}
private void initializeResources() {
masterSecret = getIntent().getParcelableExtra(MASTER_SECRET_EXTRA);
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
noImages = (TextView ) findViewById(R.id.no_images );
gridView = (RecyclerView) findViewById(R.id.media_grid);

View File

@ -20,26 +20,24 @@ import android.annotation.TargetApi;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.opengl.GLES20;
import android.os.AsyncTask;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.Recipient.RecipientModifiedListener;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
@ -60,9 +58,8 @@ import uk.co.senab.photoview.PhotoViewAttacher;
public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity implements RecipientModifiedListener {
private final static String TAG = MediaPreviewActivity.class.getSimpleName();
public final static String MASTER_SECRET_EXTRA = "master_secret";
public final static String RECIPIENT_EXTRA = "recipient";
public final static String DATE_EXTRA = "date";
public static final String RECIPIENT_EXTRA = "recipient";
public static final String DATE_EXTRA = "date";
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
@ -79,12 +76,11 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
private long date;
@Override
protected void onCreate(Bundle bundle) {
protected void onCreate(Bundle bundle, @NonNull MasterSecret masterSecret) {
this.masterSecret = masterSecret;
this.setTheme(R.style.TextSecure_DarkTheme);
dynamicLanguage.onCreate(this);
super.onCreate(bundle);
setFullscreenIfPossible();
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
@ -157,7 +153,6 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
private void initializeResources() {
final long recipientId = getIntent().getLongExtra(RECIPIENT_EXTRA, -1);
masterSecret = getIntent().getParcelableExtra(MASTER_SECRET_EXTRA);
mediaUri = getIntent().getData();
mediaType = getIntent().getType();
date = getIntent().getLongExtra(DATE_EXTRA, -1);

View File

@ -20,6 +20,7 @@ import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.util.Log;
@ -83,10 +84,13 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity
private DynamicLanguage dynamicLanguage = new DynamicLanguage();
@Override
public void onCreate(Bundle bundle) {
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
super.onCreate(bundle);
}
@Override
public void onCreate(Bundle bundle, @NonNull MasterSecret masterSecret) {
setContentView(R.layout.message_details_activity);
initializeResources();

View File

@ -18,6 +18,7 @@ package org.thoughtcrime.securesms;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
@ -50,21 +51,21 @@ import static org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData;
*
*/
public class NewConversationActivity extends PassphraseRequiredActionBarActivity {
private final static String TAG = "ContactSelectActivity";
public final static String MASTER_SECRET_EXTRA = "master_secret";
private static final String TAG = NewConversationActivity.class.getSimpleName();
private final DynamicTheme dynamicTheme = new DynamicTheme ();
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
private MasterSecret masterSecret;
private PushContactSelectionListFragment contactsFragment;
@Override
protected void onCreate(Bundle icicle) {
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
super.onCreate(icicle);
}
@Override
protected void onCreate(Bundle icicle, @NonNull MasterSecret masterSecret) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setContentView(R.layout.new_conversation_activity);
@ -77,7 +78,6 @@ public class NewConversationActivity extends PassphraseRequiredActionBarActivity
dynamicTheme.onResume(this);
dynamicLanguage.onResume(this);
getSupportActionBar().setTitle(R.string.AndroidManifest__select_contacts);
masterSecret = getIntent().getParcelableExtra(MASTER_SECRET_EXTRA);
}
@Override
@ -116,7 +116,7 @@ public class NewConversationActivity extends PassphraseRequiredActionBarActivity
final Intent resultIntent = getIntent();
final List<ContactData> selectedContacts = contactsFragment.getSelectedContacts();
if (selectedContacts != null) {
resultIntent.putParcelableArrayListExtra("contacts", new ArrayList<ContactData>(contactsFragment.getSelectedContacts()));
resultIntent.putParcelableArrayListExtra("contacts", new ArrayList<>(contactsFragment.getSelectedContacts()));
}
setResult(RESULT_OK, resultIntent);
finish();
@ -149,7 +149,6 @@ public class NewConversationActivity extends PassphraseRequiredActionBarActivity
if (recipients != null) {
Intent intent = new Intent(this, ConversationActivity.class);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.getIds());
intent.putExtra(ConversationActivity.MASTER_SECRET_EXTRA, masterSecret);
intent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, getIntent().getStringExtra(ConversationActivity.DRAFT_TEXT_EXTRA));
intent.putExtra(ConversationActivity.DRAFT_AUDIO_EXTRA, getIntent().getParcelableExtra(ConversationActivity.DRAFT_AUDIO_EXTRA));
intent.putExtra(ConversationActivity.DRAFT_VIDEO_EXTRA, getIntent().getParcelableExtra(ConversationActivity.DRAFT_VIDEO_EXTRA));

View File

@ -21,11 +21,9 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.ActionBarActivity;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.MemoryCleaner;
/**
@ -41,13 +39,10 @@ public abstract class PassphraseActivity extends BaseActionBarActivity {
protected void setMasterSecret(MasterSecret masterSecret) {
this.masterSecret = masterSecret;
Intent bindIntent = new Intent(this, KeyCachingService.class);
startService(bindIntent);
bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
protected MasterSecret getMasterSecret() {
return masterSecret;
}
protected abstract void cleanup();
private ServiceConnection serviceConnection = new ServiceConnection() {
@ -58,11 +53,12 @@ public abstract class PassphraseActivity extends BaseActionBarActivity {
PassphraseActivity.this.unbindService(PassphraseActivity.this.serviceConnection);
MemoryCleaner.clean(masterSecret);
masterSecret = null;
cleanup();
PassphraseActivity.this.setResult(RESULT_OK);
PassphraseActivity.this.finish();
Intent nextIntent = getIntent().getParcelableExtra("next_intent");
if (nextIntent != null) startActivity(nextIntent);
finish();
}
@Override

View File

@ -28,7 +28,6 @@ import android.widget.Toast;
import org.thoughtcrime.securesms.crypto.InvalidPassphraseException;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.util.MemoryCleaner;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
/**
@ -104,10 +103,6 @@ public class PassphraseChangeActivity extends PassphraseActivity {
MasterSecret masterSecret = MasterSecretUtil.changeMasterSecretPassphrase(this, original, passphrase);
TextSecurePreferences.setPasswordDisabled(this, false);
MemoryCleaner.clean(original);
MemoryCleaner.clean(passphrase);
MemoryCleaner.clean(passphraseRepeat);
setMasterSecret(masterSecret);
}
} catch (InvalidPassphraseException e) {

View File

@ -23,7 +23,6 @@ import android.support.v7.app.ActionBar;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.util.MemoryCleaner;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.VersionTracker;
@ -66,8 +65,6 @@ public class PassphraseCreateActivity extends PassphraseActivity {
masterSecret = MasterSecretUtil.generateMasterSecret(PassphraseCreateActivity.this,
passphrase);
MemoryCleaner.clean(passphrase);
MasterSecretUtil.generateAsymmetricMasterSecret(PassphraseCreateActivity.this, masterSecret);
IdentityKeyUtil.generateIdentityKeys(PassphraseCreateActivity.this, masterSecret);
VersionTracker.updateLastSeenVersion(PassphraseCreateActivity.this);

View File

@ -43,7 +43,6 @@ import android.widget.Toast;
import org.thoughtcrime.securesms.crypto.InvalidPassphraseException;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.MemoryCleaner;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.util.Util;
@ -73,6 +72,12 @@ public class PassphrasePromptActivity extends PassphraseActivity {
dynamicLanguage.onResume(this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuInflater inflater = this.getMenuInflater();
@ -102,9 +107,8 @@ public class PassphrasePromptActivity extends PassphraseActivity {
try {
Editable text = passphraseText.getText();
String passphrase = (text == null ? "" : text.toString());
MasterSecret masterSecret = MasterSecretUtil.getMasterSecret(PassphrasePromptActivity.this, passphrase);
MasterSecret masterSecret = MasterSecretUtil.getMasterSecret(this, passphrase);
MemoryCleaner.clean(passphrase);
setMasterSecret(masterSecret);
} catch (InvalidPassphraseException ipe) {
passphraseText.setText("");

View File

@ -1,42 +1,186 @@
package org.thoughtcrime.securesms;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.WindowManager;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.service.MessageRetrievalService;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
public class PassphraseRequiredActionBarActivity extends BaseActionBarActivity implements PassphraseRequiredActivity {
public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarActivity implements MasterSecretListener {
private static final String TAG = PassphraseRequiredActionBarActivity.class.getSimpleName();
private final PassphraseRequiredMixin delegate = new PassphraseRequiredMixin();
private static final int STATE_NORMAL = 0;
private static final int STATE_CREATE_PASSPHRASE = 1;
private static final int STATE_PROMPT_PASSPHRASE = 2;
private static final int STATE_UPGRADE_DATABASE = 3;
private static final int STATE_PROMPT_PUSH_REGISTRATION = 4;
private BroadcastReceiver clearKeyReceiver;
private boolean isVisible;
@Override
protected void onCreate(Bundle savedInstanceState) {
protected final void onCreate(Bundle savedInstanceState) {
onPreCreate();
final MasterSecret masterSecret = KeyCachingService.getMasterSecret(this);
routeApplicationState(masterSecret);
super.onCreate(savedInstanceState);
delegate.onCreate(this);
if (!isFinishing()) {
initializeClearKeyReceiver();
onCreate(savedInstanceState, masterSecret);
}
}
protected void onPreCreate() {}
protected void onCreate(Bundle savedInstanceState, @NonNull MasterSecret masterSecret) {}
@Override
protected void onResume() {
super.onResume();
delegate.onResume(this);
initializeScreenshotSecurity();
KeyCachingService.registerPassphraseActivityStarted(this);
MessageRetrievalService.registerActivityStarted(this);
isVisible = true;
}
@Override
protected void onPause() {
super.onPause();
delegate.onPause(this);
KeyCachingService.registerPassphraseActivityStopped(this);
MessageRetrievalService.registerActivityStopped(this);
isVisible = false;
}
@Override
protected void onDestroy() {
super.onDestroy();
delegate.onDestroy(this);
removeClearKeyReceiver(this);
}
@Override
public void onMasterSecretCleared() {
finish();
Log.w(TAG, "onMasterSecretCleared()");
if (isVisible) routeApplicationState(null);
else finish();
}
@Override
public void onNewMasterSecret(MasterSecret masterSecret) {}
protected <T extends Fragment> T initFragment(@IdRes int target,
@NonNull T fragment,
@NonNull MasterSecret masterSecret) {
Bundle args = new Bundle();
args.putParcelable("master_secret", masterSecret);
fragment.setArguments(args);
getSupportFragmentManager().beginTransaction()
.replace(target, fragment)
.commit();
return fragment;
}
private void routeApplicationState(MasterSecret masterSecret) {
Intent intent = getIntentForState(masterSecret, getApplicationState(masterSecret));
if (intent != null) {
startActivity(intent);
finish();
}
}
private Intent getIntentForState(MasterSecret masterSecret, int state) {
Log.w(TAG, "routeApplicationState(), state: " + state);
switch (state) {
case STATE_CREATE_PASSPHRASE: return getCreatePassphraseIntent();
case STATE_PROMPT_PASSPHRASE: return getPromptPassphraseIntent();
case STATE_UPGRADE_DATABASE: return getUpgradeDatabaseIntent(masterSecret);
case STATE_PROMPT_PUSH_REGISTRATION: return getPushRegistrationIntent(masterSecret);
default: return null;
}
}
private int getApplicationState(MasterSecret masterSecret) {
if (!MasterSecretUtil.isPassphraseInitialized(this)) {
return STATE_CREATE_PASSPHRASE;
} else if (masterSecret == null) {
return STATE_PROMPT_PASSPHRASE;
} else if (DatabaseUpgradeActivity.isUpdate(this)) {
return STATE_UPGRADE_DATABASE;
} else if (!TextSecurePreferences.hasPromptedPushRegistration(this)) {
return STATE_PROMPT_PUSH_REGISTRATION;
} else {
return STATE_NORMAL;
}
}
private Intent getCreatePassphraseIntent() {
return getRoutedIntent(PassphraseCreateActivity.class, getIntent(), null);
}
private Intent getPromptPassphraseIntent() {
return getRoutedIntent(PassphrasePromptActivity.class, getIntent(), null);
}
private Intent getUpgradeDatabaseIntent(MasterSecret masterSecret) {
return getRoutedIntent(DatabaseUpgradeActivity.class,
TextSecurePreferences.hasPromptedPushRegistration(this)
? getConversationListIntent()
: getPushRegistrationIntent(masterSecret),
masterSecret);
}
private Intent getPushRegistrationIntent(MasterSecret masterSecret) {
return getRoutedIntent(RegistrationActivity.class, getConversationListIntent(), masterSecret);
}
private Intent getRoutedIntent(Class<?> destination, @Nullable Intent nextIntent, @Nullable MasterSecret masterSecret) {
final Intent intent = new Intent(this, destination);
if (nextIntent != null) intent.putExtra("next_intent", nextIntent);
if (masterSecret != null) intent.putExtra("master_secret", masterSecret);
return intent;
}
private Intent getConversationListIntent() {
return new Intent(this, ConversationListActivity.class);
}
private void initializeScreenshotSecurity() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH &&
TextSecurePreferences.isScreenSecurityEnabled(this))
{
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
}
private void initializeClearKeyReceiver() {
Log.w(TAG, "initializeClearKeyReceiver()");
this.clearKeyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.w(TAG, "onReceive() for clear key event");
onMasterSecretCleared();
}
};
IntentFilter filter = new IntentFilter(KeyCachingService.CLEAR_KEY_EVENT);
registerReceiver(clearKeyReceiver, filter, KeyCachingService.KEY_PERMISSION, null);
}
private void removeClearKeyReceiver(Context context) {
if (clearKeyReceiver != null) {
context.unregisterReceiver(clearKeyReceiver);
clearKeyReceiver = null;
}
}
}

View File

@ -1,8 +0,0 @@
package org.thoughtcrime.securesms;
import org.thoughtcrime.securesms.crypto.MasterSecret;
public interface PassphraseRequiredActivity {
public void onMasterSecretCleared();
public void onNewMasterSecret(MasterSecret masterSecret);
}

View File

@ -1,102 +0,0 @@
package org.thoughtcrime.securesms;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.view.WindowManager;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.service.MessageRetrievalService;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
public class PassphraseRequiredMixin {
private BroadcastReceiver clearKeyReceiver;
private BroadcastReceiver newKeyReceiver;
public <T extends Activity & PassphraseRequiredActivity> void onCreate(T activity) {
initializeClearKeyReceiver(activity);
}
public <T extends Activity & PassphraseRequiredActivity> void onResume(T activity) {
initializeScreenshotSecurity(activity);
initializeNewKeyReceiver(activity);
initializeFromMasterSecret(activity);
KeyCachingService.registerPassphraseActivityStarted(activity);
MessageRetrievalService.registerActivityStarted(activity);
}
public <T extends Activity & PassphraseRequiredActivity> void onPause(T activity) {
removeNewKeyReceiver(activity);
KeyCachingService.registerPassphraseActivityStopped(activity);
MessageRetrievalService.registerActivityStopped(activity);
}
public <T extends Activity & PassphraseRequiredActivity> void onDestroy(T activity) {
removeClearKeyReceiver(activity);
}
private <T extends Activity & PassphraseRequiredActivity> void initializeScreenshotSecurity(T activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
if (TextSecurePreferences.isScreenSecurityEnabled(activity)) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
} else {
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
}
}
private <T extends Activity & PassphraseRequiredActivity> void initializeClearKeyReceiver(final T activity) {
this.clearKeyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
activity.onMasterSecretCleared();
}
};
IntentFilter filter = new IntentFilter(KeyCachingService.CLEAR_KEY_EVENT);
activity.registerReceiver(clearKeyReceiver, filter, KeyCachingService.KEY_PERMISSION, null);
}
private <T extends Activity & PassphraseRequiredActivity> void initializeNewKeyReceiver(final T activity) {
this.newKeyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
activity.onNewMasterSecret((MasterSecret)intent.getParcelableExtra("master_secret"));
}
};
IntentFilter filter = new IntentFilter(KeyCachingService.NEW_KEY_EVENT);
activity.registerReceiver(newKeyReceiver, filter, KeyCachingService.KEY_PERMISSION, null);
}
private <T extends Activity & PassphraseRequiredActivity> void initializeFromMasterSecret(T activity) {
MasterSecret masterSecret = KeyCachingService.getMasterSecret(activity);
if (masterSecret == null) {
activity.onMasterSecretCleared();
} else {
activity.onNewMasterSecret(masterSecret);
}
}
private void removeClearKeyReceiver(Context context) {
if (clearKeyReceiver != null) {
context.unregisterReceiver(clearKeyReceiver);
clearKeyReceiver = null;
}
}
private void removeNewKeyReceiver(Context context) {
if (newKeyReceiver != null) {
context.unregisterReceiver(newKeyReceiver);
newKeyReceiver = null;
}
}
}

View File

@ -1,45 +0,0 @@
package org.thoughtcrime.securesms;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import org.thoughtcrime.securesms.crypto.MasterSecret;
public class PassphraseRequiredSherlockListActivity extends ActionBarListActivity implements PassphraseRequiredActivity {
private final PassphraseRequiredMixin delegate = new PassphraseRequiredMixin();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
delegate.onCreate(this);
}
@Override
protected void onResume() {
super.onResume();
delegate.onResume(this);
}
@Override
protected void onPause() {
super.onPause();
delegate.onPause(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
delegate.onDestroy(this);
}
@Override
public void onMasterSecretCleared() {
finish();
}
@Override
public void onNewMasterSecret(MasterSecret masterSecret) {}
}

View File

@ -2,10 +2,12 @@ package org.thoughtcrime.securesms;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.View;
import android.widget.Button;
import org.thoughtcrime.securesms.preferences.MmsPreferencesActivity;
import org.thoughtcrime.securesms.crypto.MasterSecret;
public class PromptMmsActivity extends PassphraseRequiredActionBarActivity {
@ -13,9 +15,7 @@ public class PromptMmsActivity extends PassphraseRequiredActionBarActivity {
private Button cancelButton;
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
protected void onCreate(Bundle bundle, @NonNull MasterSecret masterSecret) {
setContentView(R.layout.prompt_apn_activity);
initializeResources();
}

View File

@ -18,11 +18,13 @@ package org.thoughtcrime.securesms;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.util.DirectoryHelper;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
@ -50,11 +52,13 @@ public class PushContactSelectionActivity extends PassphraseRequiredActionBarAct
private PushContactSelectionListFragment contactsFragment;
@Override
protected void onCreate(Bundle icicle) {
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
super.onCreate(icicle);
}
@Override
protected void onCreate(Bundle icicle, @NonNull MasterSecret masterSecret) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setContentView(R.layout.push_contact_selection_activity);

View File

@ -21,6 +21,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
@ -41,7 +42,6 @@ import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.sms.IncomingPreKeyBundleMessage;
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.MemoryCleaner;
import org.whispersystems.libaxolotl.IdentityKey;
import org.whispersystems.libaxolotl.InvalidKeyException;
import org.whispersystems.libaxolotl.InvalidMessageException;
@ -60,7 +60,7 @@ import java.io.IOException;
* @author Moxie Marlinspike
*/
public class ReceiveKeyActivity extends BaseActivity {
public class ReceiveKeyActivity extends PassphraseRequiredActionBarActivity {
private TextView descriptionText;
@ -76,8 +76,8 @@ public class ReceiveKeyActivity extends BaseActivity {
private IdentityKey identityKey;
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
protected void onCreate(Bundle state, @NonNull MasterSecret masterSecret) {
this.masterSecret = masterSecret;
setContentView(R.layout.receive_key_activity);
initializeResources();
@ -91,12 +91,6 @@ public class ReceiveKeyActivity extends BaseActivity {
initializeListeners();
}
@Override
protected void onDestroy() {
MemoryCleaner.clean(masterSecret);
super.onDestroy();
}
private void initializeText() {
SpannableString spannableString = new SpannableString(getString(R.string.ReceiveKeyActivity_the_signature_on_this_key_exchange_is_different) + " " +
getString(R.string.ReceiveKeyActivity_you_may_wish_to_verify_this_contact));
@ -105,7 +99,6 @@ public class ReceiveKeyActivity extends BaseActivity {
public void onClick(View widget) {
Intent intent = new Intent(ReceiveKeyActivity.this, VerifyIdentityActivity.class);
intent.putExtra("recipient", recipient.getRecipientId());
intent.putExtra("master_secret", masterSecret);
intent.putExtra("remote_identity", new IdentityKeyParcelable(identityKey));
startActivity(intent);
}
@ -137,7 +130,6 @@ public class ReceiveKeyActivity extends BaseActivity {
this.recipient = RecipientFactory.getRecipientForId(this, getIntent().getLongExtra("recipient", -1), true);
this.recipientDeviceId = getIntent().getIntExtra("recipient_device_id", -1);
this.messageId = getIntent().getLongExtra("message_id", -1);
this.masterSecret = getIntent().getParcelableExtra("master_secret");
}
private void initializeListeners() {

View File

@ -25,9 +25,9 @@ import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.util.Dialogs;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.textsecure.api.util.PhoneNumberFormatter;
@ -284,7 +284,7 @@ public class RegistrationActivity extends BaseActionBarActivity {
Intent nextIntent = getIntent().getParcelableExtra("next_intent");
if (nextIntent == null) {
nextIntent = new Intent(RegistrationActivity.this, RoutingActivity.class);
nextIntent = new Intent(RegistrationActivity.this, ConversationListActivity.class);
}
startActivity(nextIntent);

View File

@ -33,6 +33,7 @@ import android.widget.Toast;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.push.TextSecureCommunicationFactory;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.service.RegistrationService;
import org.thoughtcrime.securesms.util.Dialogs;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
@ -330,7 +331,7 @@ public class RegistrationProgressActivity extends BaseActionBarActivity {
}
shutdownService();
startActivity(new Intent(this, RoutingActivity.class));
startActivity(new Intent(this, ConversationListActivity.class));
finish();
}

View File

@ -1,284 +0,0 @@
package org.thoughtcrime.securesms;
import android.content.Intent;
import android.net.Uri;
import android.webkit.MimeTypeMap;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.crypto.MasterSecret;
public class RoutingActivity extends PassphraseRequiredActionBarActivity {
private static final int STATE_CREATE_PASSPHRASE = 1;
private static final int STATE_PROMPT_PASSPHRASE = 2;
private static final int STATE_CONVERSATION_OR_LIST = 3;
private static final int STATE_UPGRADE_DATABASE = 4;
private static final int STATE_PROMPT_PUSH_REGISTRATION = 5;
private MasterSecret masterSecret = null;
private boolean isVisible = false;
private boolean canceledResult = false;
private boolean newIntent = false;
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
this.newIntent = true;
}
@Override
public void onResume() {
if (this.canceledResult && !this.newIntent) {
finish();
}
this.newIntent = false;
this.canceledResult = false;
this.isVisible = true;
super.onResume();
}
@Override
public void onPause() {
this.isVisible = false;
super.onPause();
}
@Override
public void onNewMasterSecret(MasterSecret masterSecret) {
this.masterSecret = masterSecret;
if (isVisible) {
routeApplicationState();
}
}
@Override
public void onMasterSecretCleared() {
this.masterSecret = null;
if (isVisible) {
routeApplicationState();
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_CANCELED) {
canceledResult = true;
}
}
private void routeApplicationState() {
int state = getApplicationState();
switch (state) {
case STATE_CREATE_PASSPHRASE: handleCreatePassphrase(); break;
case STATE_PROMPT_PASSPHRASE: handlePromptPassphrase(); break;
case STATE_CONVERSATION_OR_LIST: handleDisplayConversationOrList(); break;
case STATE_UPGRADE_DATABASE: handleUpgradeDatabase(); break;
case STATE_PROMPT_PUSH_REGISTRATION: handlePushRegistration(); break;
}
}
private void handleCreatePassphrase() {
Intent intent = new Intent(this, PassphraseCreateActivity.class);
startActivityForResult(intent, 1);
}
private void handlePromptPassphrase() {
Intent intent = new Intent(this, PassphrasePromptActivity.class);
startActivityForResult(intent, 2);
}
private void handleUpgradeDatabase() {
Intent intent = new Intent(this, DatabaseUpgradeActivity.class);
intent.putExtra("master_secret", masterSecret);
intent.putExtra("next_intent", TextSecurePreferences.hasPromptedPushRegistration(this) ?
getConversationListIntent() : getPushRegistrationIntent());
startActivity(intent);
finish();
}
private void handlePushRegistration() {
Intent intent = getPushRegistrationIntent();
intent.putExtra("next_intent", getConversationListIntent());
startActivity(intent);
finish();
}
private void handleDisplayConversationOrList() {
final ConversationParameters parameters = getConversationParameters();
final Intent intent;
if (isShareAction()) intent = getShareIntent(parameters);
else if (parameters.recipients != null) intent = getConversationIntent(parameters);
else intent = getConversationListIntent();
startActivity(intent);
finish();
}
private Intent getConversationIntent(ConversationParameters parameters) {
Intent intent = new Intent(this, ConversationActivity.class);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, parameters.recipients != null ? parameters.recipients.getIds() : new long[]{});
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, parameters.thread);
intent.putExtra(ConversationActivity.MASTER_SECRET_EXTRA, masterSecret);
intent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, parameters.draftText);
intent.putExtra(ConversationActivity.DRAFT_IMAGE_EXTRA, parameters.draftImage);
intent.putExtra(ConversationActivity.DRAFT_AUDIO_EXTRA, parameters.draftAudio);
intent.putExtra(ConversationActivity.DRAFT_VIDEO_EXTRA, parameters.draftVideo);
return intent;
}
private Intent getShareIntent(ConversationParameters parameters) {
Intent intent = new Intent(this, ShareActivity.class);
intent.putExtra("master_secret", masterSecret);
if (parameters != null) {
intent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, parameters.draftText);
intent.putExtra(ConversationActivity.DRAFT_IMAGE_EXTRA, parameters.draftImage);
intent.putExtra(ConversationActivity.DRAFT_AUDIO_EXTRA, parameters.draftAudio);
intent.putExtra(ConversationActivity.DRAFT_VIDEO_EXTRA, parameters.draftVideo);
}
return intent;
}
private Intent getConversationListIntent() {
Intent intent = new Intent(this, ConversationListActivity.class);
intent.putExtra("master_secret", masterSecret);
return intent;
}
private Intent getPushRegistrationIntent() {
Intent intent = new Intent(this, RegistrationActivity.class);
intent.putExtra("master_secret", masterSecret);
return intent;
}
private int getApplicationState() {
if (!MasterSecretUtil.isPassphraseInitialized(this))
return STATE_CREATE_PASSPHRASE;
if (masterSecret == null)
return STATE_PROMPT_PASSPHRASE;
if (DatabaseUpgradeActivity.isUpdate(this))
return STATE_UPGRADE_DATABASE;
if (!TextSecurePreferences.hasPromptedPushRegistration(this))
return STATE_PROMPT_PUSH_REGISTRATION;
return STATE_CONVERSATION_OR_LIST;
}
private ConversationParameters getConversationParameters() {
if (isSendAction()) {
return getConversationParametersForSendAction();
} else if (isShareAction()) {
return getConversationParametersForShareAction();
} else {
return getConversationParametersForInternalAction();
}
}
private ConversationParameters getConversationParametersForSendAction() {
Recipients recipients;
String body = getIntent().getStringExtra("sms_body");
long threadId = getIntent().getLongExtra("thread_id", -1);
Uri data = getIntent().getData();
if (data != null && data.getSchemeSpecificPart() != null) {
recipients = RecipientFactory.getRecipientsFromString(this, data.getSchemeSpecificPart(), false);
threadId = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipients);
} else {
recipients = null;
}
return new ConversationParameters(threadId, recipients, body, null, null, null);
}
private ConversationParameters getConversationParametersForShareAction() {
String type = getIntent().getType();
String draftText = getIntent().getStringExtra(Intent.EXTRA_TEXT);
Uri draftImage = null;
Uri draftAudio = null;
Uri draftVideo = null;
Uri streamExtra = getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
if (streamExtra != null) {
type = getMimeType(streamExtra);
}
if (type != null && type.startsWith("image/")) {
draftImage = streamExtra;
} else if (type != null && type.startsWith("audio/")) {
draftAudio = streamExtra;
} else if (type != null && type.startsWith("video/")) {
draftVideo = streamExtra;
}
return new ConversationParameters(-1, null, draftText, draftImage, draftAudio, draftVideo);
}
private String getMimeType(Uri uri) {
String type = getContentResolver().getType(uri);
if (type == null) {
String extension = MimeTypeMap.getFileExtensionFromUrl(uri.toString());
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}
private ConversationParameters getConversationParametersForInternalAction() {
long threadId = getIntent().getLongExtra("thread_id", -1);
long[] recipientIds = getIntent().getLongArrayExtra("recipients");
Recipients recipients = recipientIds == null ? null : RecipientFactory.getRecipientsForIds(this, recipientIds, true);
return new ConversationParameters(threadId, recipients, null, null, null, null);
}
private boolean isShareAction() {
return Intent.ACTION_SEND.equals(getIntent().getAction());
}
private boolean isSendAction() {
return Intent.ACTION_SENDTO.equals(getIntent().getAction());
}
private static class ConversationParameters {
public final long thread;
public final Recipients recipients;
public final String draftText;
public final Uri draftImage;
public final Uri draftAudio;
public final Uri draftVideo;
public ConversationParameters(long thread, Recipients recipients,
String draftText, Uri draftImage, Uri draftAudio, Uri draftVideo)
{
this.thread = thread;
this.recipients = recipients;
this.draftText = draftText;
this.draftImage = draftImage;
this.draftAudio = draftAudio;
this.draftVideo = draftVideo;
}
}
}

View File

@ -20,15 +20,18 @@ package org.thoughtcrime.securesms;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.webkit.MimeTypeMap;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.MemoryCleaner;
import ws.com.google.android.mms.ContentType;
/**
* An activity to quickly share content with contacts
@ -37,23 +40,20 @@ import org.thoughtcrime.securesms.util.MemoryCleaner;
*/
public class ShareActivity extends PassphraseRequiredActionBarActivity
implements ShareFragment.ConversationSelectedListener
{
public final static String MASTER_SECRET_EXTRA = "master_secret";
{
private final DynamicTheme dynamicTheme = new DynamicTheme ();
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
private ShareFragment fragment;
private MasterSecret masterSecret;
@Override
public void onCreate(Bundle icicle) {
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
super.onCreate(icicle);
}
@Override
protected void onCreate(Bundle icicle, @NonNull MasterSecret masterSecret) {
setContentView(R.layout.share_activity);
initializeResources();
initFragment(R.id.drawer_layout, new ShareFragment(), masterSecret);
}
@Override
@ -76,12 +76,6 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
if (!isFinishing()) finish();
}
@Override
public void onDestroy() {
MemoryCleaner.clean(masterSecret);
super.onDestroy();
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuInflater inflater = this.getMenuInflater();
@ -102,12 +96,6 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
return false;
}
@Override
public void onMasterSecretCleared() {
startActivity(new Intent(this, RoutingActivity.class));
super.onMasterSecretCleared();
}
private void handleNewConversation() {
Intent intent = getBaseShareIntent(NewConversationActivity.class);
startActivity(intent);
@ -127,29 +115,32 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
startActivity(intent);
}
private void initializeResources() {
this.masterSecret = getIntent().getParcelableExtra(MASTER_SECRET_EXTRA);
this.fragment = (ShareFragment)this.getSupportFragmentManager()
.findFragmentById(R.id.fragment_content);
this.fragment.setMasterSecret(masterSecret);
}
private Intent getBaseShareIntent(final Class<?> target) {
final Intent intent = new Intent(this, target);
final Intent originalIntent = getIntent();
final String draftText = originalIntent.getStringExtra(ConversationActivity.DRAFT_TEXT_EXTRA);
final Uri draftImage = originalIntent.getParcelableExtra(ConversationActivity.DRAFT_IMAGE_EXTRA);
final Uri draftAudio = originalIntent.getParcelableExtra(ConversationActivity.DRAFT_AUDIO_EXTRA);
final Uri draftVideo = originalIntent.getParcelableExtra(ConversationActivity.DRAFT_VIDEO_EXTRA);
final Intent intent = new Intent(this, target);
final String textExtra = getIntent().getStringExtra(ConversationActivity.DRAFT_TEXT_EXTRA);
final Uri streamExtra = getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
final String type = streamExtra != null ? getMimeType(streamExtra) : getIntent().getType();
intent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, draftText);
intent.putExtra(ConversationActivity.DRAFT_IMAGE_EXTRA, draftImage);
intent.putExtra(ConversationActivity.DRAFT_AUDIO_EXTRA, draftAudio);
intent.putExtra(ConversationActivity.DRAFT_VIDEO_EXTRA, draftVideo);
intent.putExtra(NewConversationActivity.MASTER_SECRET_EXTRA, masterSecret);
if (ContentType.isImageType(type)) {
intent.putExtra(ConversationActivity.DRAFT_IMAGE_EXTRA, streamExtra);
} else if (ContentType.isAudioType(type)) {
intent.putExtra(ConversationActivity.DRAFT_AUDIO_EXTRA, streamExtra);
} else if (ContentType.isVideoType(type)) {
intent.putExtra(ConversationActivity.DRAFT_VIDEO_EXTRA, streamExtra);
}
intent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, textExtra);
return intent;
}
}
private String getMimeType(Uri uri) {
String type = getContentResolver().getType(uri);
if (type == null) {
String extension = MimeTypeMap.getFileExtensionFromUrl(uri.toString());
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}
}

View File

@ -43,6 +43,12 @@ public class ShareFragment extends ListFragment implements LoaderManager.LoaderC
private ConversationSelectedListener listener;
private MasterSecret masterSecret;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
masterSecret = getArguments().getParcelable("master_secret");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
return inflater.inflate(R.layout.share_fragment, container, false);
@ -72,13 +78,6 @@ public class ShareFragment extends ListFragment implements LoaderManager.LoaderC
}
}
public void setMasterSecret(MasterSecret masterSecret) {
if (this.masterSecret != masterSecret) {
this.masterSecret = masterSecret;
initializeListAdapter();
}
}
private void initializeListAdapter() {
this.setListAdapter(new ShareListAdapter(getActivity(), null, masterSecret));
getListView().setRecyclerListener((ShareListAdapter) getListAdapter());

View File

@ -0,0 +1,39 @@
package org.thoughtcrime.securesms;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
public class SmsSendtoActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
startActivity(getNextIntent(getIntent()));
finish();
super.onCreate(savedInstanceState);
}
private Intent getNextIntent(Intent original) {
String body = original.getStringExtra("sms_body");
String data = original.getData().getSchemeSpecificPart();
Recipients recipients = RecipientFactory.getRecipientsFromString(this, data, false);
long threadId = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipients);
final Intent nextIntent;
if (recipients == null || recipients.isEmpty()) {
nextIntent = new Intent(this, NewConversationActivity.class);
nextIntent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, body);
Toast.makeText(this, R.string.ConversationActivity_specify_recipient, Toast.LENGTH_LONG).show();
} else {
nextIntent = new Intent(this, ConversationActivity.class);
nextIntent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, body);
nextIntent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
nextIntent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.getIds());
}
return nextIntent;
}
}

View File

@ -18,6 +18,7 @@
package org.thoughtcrime.securesms;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.widget.TextView;
import android.widget.Toast;
@ -29,7 +30,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.MemoryCleaner;
import org.whispersystems.libaxolotl.AxolotlAddress;
import org.whispersystems.libaxolotl.IdentityKey;
import org.whispersystems.libaxolotl.state.SessionRecord;
@ -53,10 +53,14 @@ public class VerifyIdentityActivity extends KeyScanningActivity {
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
@Override
public void onCreate(Bundle state) {
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
super.onCreate(state);
}
@Override
protected void onCreate(Bundle state, @NonNull MasterSecret masterSecret) {
this.masterSecret = masterSecret;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setContentView(R.layout.verify_identity_activity);
@ -73,12 +77,6 @@ public class VerifyIdentityActivity extends KeyScanningActivity {
}
@Override
protected void onDestroy() {
MemoryCleaner.clean(masterSecret);
super.onDestroy();
}
private void initializeLocalIdentityKey() {
if (!IdentityKeyUtil.hasIdentityKey(this)) {
localIdentityFingerprint.setText(R.string.VerifyIdentityActivity_you_do_not_have_an_identity_key);
@ -116,7 +114,6 @@ public class VerifyIdentityActivity extends KeyScanningActivity {
this.localIdentityFingerprint = (TextView)findViewById(R.id.you_read);
this.remoteIdentityFingerprint = (TextView)findViewById(R.id.friend_reads);
this.recipient = RecipientFactory.getRecipientForId(this, this.getIntent().getLongExtra("recipient", -1), true);
this.masterSecret = this.getIntent().getParcelableExtra("master_secret");
}
@Override

View File

@ -17,8 +17,10 @@
package org.thoughtcrime.securesms;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.widget.TextView;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.whispersystems.libaxolotl.IdentityKey;
import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable;
@ -36,8 +38,7 @@ public class ViewIdentityActivity extends KeyScanningActivity {
private IdentityKey identityKey;
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
protected void onCreate(Bundle state, @NonNull MasterSecret masterSecret) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setContentView(R.layout.view_identity_activity);

View File

@ -18,13 +18,14 @@
package org.thoughtcrime.securesms;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable;
import org.thoughtcrime.securesms.crypto.MasterSecret;
/**
* Activity that displays the local identity key and offers the option to regenerate it.
@ -33,12 +34,13 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable;
*/
public class ViewLocalIdentityActivity extends ViewIdentityActivity {
public void onCreate(Bundle bundle) {
@Override
protected void onCreate(Bundle icicle, @NonNull MasterSecret masterSecret) {
getIntent().putExtra(ViewIdentityActivity.IDENTITY_KEY,
new IdentityKeyParcelable(IdentityKeyUtil.getIdentityKey(this)));
getIntent().putExtra(ViewIdentityActivity.TITLE,
getString(R.string.ViewIdentityActivity_my_identity_fingerprint));
super.onCreate(bundle);
super.onCreate(icicle, masterSecret);
}
@Override

View File

@ -39,8 +39,8 @@ import android.text.TextUtils;
import android.text.style.StyleSpan;
import android.util.Log;
import org.thoughtcrime.securesms.ConversationActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.RoutingActivity;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
@ -84,7 +84,7 @@ public class MessageNotifier {
if (visibleThread == threadId) {
sendInThreadNotification(context);
} else {
Intent intent = new Intent(context, RoutingActivity.class);
Intent intent = new Intent(context, ConversationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("recipients", recipients.getIds());
intent.putExtra("thread_id", threadId);
@ -228,7 +228,7 @@ public class MessageNotifier {
notificationState.getMessageCount()));
builder.setContentText(String.format(context.getString(R.string.MessageNotifier_most_recent_from_s),
notifications.get(0).getIndividualRecipientName()));
builder.setContentIntent(PendingIntent.getActivity(context, 0, new Intent(context, RoutingActivity.class), 0));
builder.setContentIntent(PendingIntent.getActivity(context, 0, new Intent(context, ConversationActivity.class), 0));
builder.setContentInfo(String.valueOf(notificationState.getMessageCount()));
builder.setNumber(notificationState.getMessageCount());

View File

@ -6,7 +6,7 @@ import android.content.Intent;
import android.net.Uri;
import android.text.SpannableStringBuilder;
import org.thoughtcrime.securesms.RoutingActivity;
import org.thoughtcrime.securesms.ConversationActivity;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.Util;
@ -70,16 +70,12 @@ public class NotificationItem {
}
public PendingIntent getPendingIntent(Context context) {
Intent intent = new Intent(context, RoutingActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Intent intent = new Intent(context, ConversationActivity.class);
if (recipients != null || threadRecipients != null) {
if (threadRecipients != null) intent.putExtra("recipients", threadRecipients.getIds());
else intent.putExtra("recipients", recipients.getIds());
intent.putExtra("thread_id", threadId);
}
Recipients notifyRecipients = threadRecipients != null ? threadRecipients : recipients;
if (notifyRecipients != null) intent.putExtra("recipients", notifyRecipients.getIds());
intent.putExtra("thread_id", threadId);
intent.setData((Uri.parse("custom://"+System.currentTimeMillis())));
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

View File

@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
import java.util.concurrent.TimeUnit;
public class AppProtectionPreferenceFragment extends PreferenceFragment {
private MasterSecret masterSecret;
private CheckBoxPreference disablePassphrase;
@Override
@ -34,6 +35,7 @@ public class AppProtectionPreferenceFragment extends PreferenceFragment {
super.onCreate(paramBundle);
addPreferencesFromResource(R.xml.preferences_app_protection);
masterSecret = getArguments().getParcelable("master_secret");
disablePassphrase = (CheckBoxPreference) this.findPreference("pref_enable_passphrase_temporary");
this.findPreference(TextSecurePreferences.CHANGE_PASSPHRASE_PREF)
@ -126,12 +128,10 @@ public class AppProtectionPreferenceFragment extends PreferenceFragment {
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);

View File

@ -17,6 +17,7 @@
package org.thoughtcrime.securesms.preferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
@ -26,25 +27,22 @@ import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.MemoryCleaner;
public class MmsPreferencesActivity extends PassphraseRequiredActionBarActivity {
private MasterSecret masterSecret;
private final DynamicTheme dynamicTheme = new DynamicTheme();
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
@Override
protected void onCreate(Bundle icicle) {
protected void onPreCreate() {
dynamicTheme.onCreate(this);
dynamicLanguage.onCreate(this);
super.onCreate(icicle);
}
@Override
protected void onCreate(Bundle icicle, @NonNull MasterSecret masterSecret) {
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
masterSecret = getIntent().getParcelableExtra("master_secret");
Fragment fragment = new MmsPreferencesFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
@ -60,13 +58,6 @@ public class MmsPreferencesActivity extends PassphraseRequiredActionBarActivity
dynamicLanguage.onResume(this);
}
@Override
public void onDestroy() {
MemoryCleaner.clean(masterSecret);
MemoryCleaner.clean((MasterSecret) getIntent().getParcelableExtra("master_secret"));
super.onDestroy();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {

View File

@ -17,8 +17,8 @@ import android.os.PowerManager.WakeLock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import org.thoughtcrime.securesms.ConversationListActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.RoutingActivity;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.SmsMigrator;
import org.thoughtcrime.securesms.database.SmsMigrator.ProgressDescription;
@ -28,8 +28,8 @@ import java.util.concurrent.Executors;
public class ApplicationMigrationService extends Service
implements SmsMigrator.SmsMigrationProgressListener
{
{
private static final String TAG = ApplicationMigrationService.class.getSimpleName();
public static final String MIGRATE_DATABASE = "org.thoughtcrime.securesms.ApplicationMigration.MIGRATE_DATABSE";
public static final String COMPLETED_ACTION = "org.thoughtcrime.securesms.ApplicationMigrationService.COMPLETED";
private static final String PREFERENCES_NAME = "SecureSMS";
@ -128,7 +128,7 @@ public class ApplicationMigrationService extends Service
builder.setContentText(getString(R.string.ApplicationMigrationService_import_in_progress));
builder.setOngoing(true);
builder.setProgress(100, 0, false);
builder.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, RoutingActivity.class), 0));
builder.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, ConversationListActivity.class), 0));
stopForeground(true);
startForeground(4242, builder.build());
@ -141,7 +141,7 @@ public class ApplicationMigrationService extends Service
public ImportRunnable(Intent intent) {
this.masterSecret = intent.getParcelableExtra("master_secret");
Log.w("ApplicationMigrationService", "Service got mastersecret: " + masterSecret);
Log.w(TAG, "Service got mastersecret: " + masterSecret);
}
@Override
@ -184,7 +184,7 @@ public class ApplicationMigrationService extends Service
builder.setSmallIcon(R.drawable.icon_notification);
builder.setContentTitle("Import Complete");
builder.setContentText("TextSecure system database import is complete.");
builder.setContentIntent(PendingIntent.getActivity(context, 0, new Intent(context, RoutingActivity.class), 0));
builder.setContentIntent(PendingIntent.getActivity(context, 0, new Intent(context, ConversationListActivity.class), 0));
builder.setWhen(System.currentTimeMillis());
builder.setDefaults(Notification.DEFAULT_VIBRATE);
builder.setAutoCancel(true);

View File

@ -33,10 +33,10 @@ import android.util.Log;
import android.widget.RemoteViews;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.ConversationListActivity;
import org.thoughtcrime.securesms.DatabaseUpgradeActivity;
import org.thoughtcrime.securesms.DummyActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.RoutingActivity;
import org.thoughtcrime.securesms.crypto.InvalidPassphraseException;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
@ -121,6 +121,7 @@ public class KeyCachingService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent == null) return START_NOT_STICKY;
Log.w("KeyCachingService", "onStartCommand, " + intent.getAction());
if (intent.getAction() != null) {
switch (intent.getAction()) {
@ -138,6 +139,7 @@ public class KeyCachingService extends Service {
@Override
public void onCreate() {
Log.w("KeyCachingService", "onCreate()");
super.onCreate();
this.pending = PendingIntent.getService(this, 0, new Intent(PASSPHRASE_EXPIRED_EVENT, null,
this, KeyCachingService.class), 0);
@ -186,7 +188,8 @@ public class KeyCachingService extends Service {
}
private void handleClearKey() {
this.masterSecret = null;
Log.w("KeyCachingService", "handleClearKey()");
KeyCachingService.masterSecret = null;
stopForeground(true);
Intent intent = new Intent(CLEAR_KEY_EVENT);
@ -216,7 +219,7 @@ public class KeyCachingService extends Service {
private void startTimeoutIfAppropriate() {
boolean timeoutEnabled = TextSecurePreferences.isPassphraseTimeoutEnabled(this);
if ((activitiesRunning == 0) && (this.masterSecret != null) && timeoutEnabled && !TextSecurePreferences.isPasswordDisabled(this)) {
if ((activitiesRunning == 0) && (KeyCachingService.masterSecret != null) && timeoutEnabled && !TextSecurePreferences.isPasswordDisabled(this)) {
long timeoutMinutes = TextSecurePreferences.getPassphraseTimeoutInterval(this);
long timeoutMillis = TimeUnit.MINUTES.toMillis(timeoutMinutes);
@ -230,6 +233,7 @@ public class KeyCachingService extends Service {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void foregroundServiceModern() {
Log.w("KeyCachingService", "foregrounding KCS");
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle(getString(R.string.KeyCachingService_passphrase_cached));
@ -292,7 +296,6 @@ public class KeyCachingService extends Service {
Log.w("service", "Broadcasting new secret...");
Intent intent = new Intent(NEW_KEY_EVENT);
intent.putExtra("master_secret", masterSecret);
intent.setPackage(getApplicationContext().getPackageName());
sendBroadcast(intent, KEY_PERMISSION);
@ -306,7 +309,7 @@ public class KeyCachingService extends Service {
}
private PendingIntent buildLaunchIntent() {
Intent intent = new Intent(this, RoutingActivity.class);
Intent intent = new Intent(this, ConversationListActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent launchIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
return launchIntent;

View File

@ -8,8 +8,8 @@ import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import org.thoughtcrime.securesms.ConversationListActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.RoutingActivity;
public class RegistrationNotifier extends BroadcastReceiver {
@Override
@ -18,7 +18,7 @@ public class RegistrationNotifier extends BroadcastReceiver {
builder.setSmallIcon(R.drawable.icon_notification);
builder.setContentTitle(intent.getStringExtra(RegistrationService.NOTIFICATION_TITLE));
builder.setContentText(intent.getStringExtra(RegistrationService.NOTIFICATION_TEXT));
builder.setContentIntent(PendingIntent.getActivity(context, 0, new Intent(context, RoutingActivity.class), 0));
builder.setContentIntent(PendingIntent.getActivity(context, 0, new Intent(context, ConversationListActivity.class), 0));
builder.setWhen(System.currentTimeMillis());
builder.setDefaults(Notification.DEFAULT_VIBRATE);
builder.setAutoCancel(true);

View File

@ -1,82 +0,0 @@
/**
* Copyright (C) 2011 Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms.util;
import org.thoughtcrime.securesms.crypto.MasterSecret;
/**
* This is not straightforward in Java, but this class makes
* a best-effort attempt to clean up memory in immutable objects.
*
* @author Moxie Marlinspike
*/
public class MemoryCleaner {
// XXX This is basically not happening for now.
// The problem is that now secrets are moving
// through both Intents and binder calls, which
// means sometimes they're shared memory and sometimes
// they're not. We're going to need to do a lot more
// work in order to accurately keep track of when to
// wipe this within an Activity lifecycle. =(
public static void clean(MasterSecret masterSecret) {
// if (masterSecret == null)
// return;
//
// try {
// SecretKeySpec cipherKey = masterSecret.getEncryptionKey();
// SecretKeySpec macKey = masterSecret.getMacKey();
//
// Field keyField = SecretKeySpec.class.getDeclaredField("key");
// keyField.setAccessible(true);
//
// byte[] cipherKeyField = (byte[]) keyField.get(cipherKey);
// byte[] macKeyField = (byte[]) keyField.get(macKey);
//
// Arrays.fill(cipherKeyField, (byte)0x00);
// Arrays.fill(macKeyField, (byte)0x00);
//
// } catch (NoSuchFieldException nsfe) {
// Log.w("MemoryCleaner", nsfe);
// } catch (IllegalArgumentException e) {
// Log.w("MemoryCleaner", e);
// } catch (IllegalAccessException e) {
// Log.w("MemoryCleaner", e);
// }
}
public static void clean(String string) {
// if (string == null)
// return;
//
// try {
// Field charArrayField = String.class.getDeclaredField("value");
// charArrayField.setAccessible(true);
//
// char[] internalBuffer = (char[])charArrayField.get(string);
//
// Arrays.fill(internalBuffer, 'A');
// } catch (NoSuchFieldException nsfe) {
// Log.w("MemoryCleaner", nsfe);
// } catch (IllegalArgumentException e) {
// Log.w("MemoryCleaner", e);
// } catch (IllegalAccessException e) {
// Log.w("MemoryCleaner", e);
// }
}
}