Switch import/export activity from tabs to cards

// FREEBIE
This commit is contained in:
Moxie Marlinspike 2017-03-15 16:53:15 -07:00
parent a8366387ab
commit 9273f5cc67
7 changed files with 260 additions and 588 deletions

View File

@ -1,100 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:gravity="center_vertical">
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_gravity="center_vertical"
android:padding="8dip">
<!--LinearLayout android:id="@+id/export_encrypted_backup"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:background="@drawable/clickable_card_light"
android:orientation="vertical">
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:src="@drawable/encrypted_backup"/>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Registration.Description"
android:text="@string/export_fragment__export_encrypted_backup"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/export_fragment__export_an_encrypted_backup_to_the_sd_card"/>
</LinearLayout>
</LinearLayout>
</LinearLayout-->
<LinearLayout android:id="@+id/export_plaintext_backup"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:background="?import_export_item_card_background"
android:orientation="vertical"
android:focusable="true">
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:layout_marginEnd="10dip"
android:src="?plaintext_backup"/>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
style="@style/Registration.Description"
android:text="@string/export_fragment__export_plaintext_backup"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/export_fragment__export_a_plaintext_backup_compatible_with"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,189 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_gravity="center_vertical"
android:gravity="center_vertical">
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_gravity="center_vertical"
android:padding="8dip">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardElevation="3dp"
card_view:cardCornerRadius="3dp"
card_view:cardUseCompatPadding="true">
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/import_export_fragment__import"
android:textSize="20sp"/>
</FrameLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/gray10"/>
<LinearLayout android:id="@+id/import_sms"
android:clickable="true"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:layout_marginEnd="10dip"
android:src="?import_sms"/>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
style="@style/Registration.Description"
android:text="@string/import_fragment__import_system_sms_database"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/import_fragment__import_the_database_from_the_default_system"/>
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/gray10"/>
<LinearLayout android:id="@+id/import_plaintext_backup"
android:clickable="true"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:layout_marginEnd="10dip"
android:src="?plaintext_backup"/>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
style="@style/Registration.Description"
android:text="@string/import_fragment__import_plaintext_backup"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/import_fragment__import_a_plaintext_backup_file"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:layout_marginTop="20dp"
card_view:cardElevation="3dp"
card_view:cardCornerRadius="2dp"
card_view:cardUseCompatPadding="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/export"
android:textSize="20sp"/>
</FrameLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/gray10"/>
<LinearLayout android:id="@+id/export_plaintext_backup"
android:clickable="true"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:layout_marginEnd="10dip"
android:src="?plaintext_backup"/>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
style="@style/Registration.Description"
android:text="@string/export_fragment__export_plaintext_backup"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/export_fragment__export_a_plaintext_backup_compatible_with"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</ScrollView>

View File

@ -1,146 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:gravity="center_vertical">
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_gravity="center_vertical"
android:padding="8dip">
<LinearLayout android:id="@+id/import_sms"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?import_export_item_card_background"
android:focusable="true"
android:orientation="vertical">
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:layout_marginEnd="10dip"
android:src="?import_sms"/>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
style="@style/Registration.Description"
android:text="@string/import_fragment__import_system_sms_database"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/import_fragment__import_the_database_from_the_default_system"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout android:id="@+id/import_encrypted_backup"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:background="?import_export_item_card_background"
android:focusable="true"
android:orientation="vertical">
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:layout_marginEnd="10dip"
android:src="?encrypted_backup"/>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
style="@style/Registration.Description"
android:text="@string/import_fragment__restore_encrypted_backup"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/import_fragment__restore_a_previously_exported_encrypted_signal_backup"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout android:id="@+id/import_plaintext_backup"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:background="?import_export_item_card_background"
android:focusable="true"
android:orientation="vertical">
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:layout_marginEnd="10dip"
android:src="?plaintext_backup"/>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
style="@style/Registration.Description"
android:text="@string/import_fragment__import_plaintext_backup"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/import_fragment__import_a_plaintext_backup_file"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -845,6 +845,9 @@
<!-- giphy_fragment --> <!-- giphy_fragment -->
<string name="giphy_fragment__nothing_found">Nothing found</string> <string name="giphy_fragment__nothing_found">Nothing found</string>
<!-- import_export_fragment -->
<string name="import_export_fragment__export">Export</string>
<string name="import_export_fragment__import">Import</string>
<!-- log_submit_activity --> <!-- log_submit_activity -->
<string name="log_submit_activity__log_fetch_failed">Could not read the log on your device. You can still use ADB to get a debug log instead.</string> <string name="log_submit_activity__log_fetch_failed">Could not read the log on your device. You can still use ADB to get a debug log instead.</string>

View File

@ -1,196 +0,0 @@
package org.thoughtcrime.securesms;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.NoExternalStorageException;
import org.thoughtcrime.securesms.database.PlaintextBackupExporter;
import java.io.IOException;
public class ExportFragment extends Fragment {
private static final int SUCCESS = 0;
private static final int NO_SD_CARD = 1;
private static final int IO_ERROR = 2;
private MasterSecret masterSecret;
public void setMasterSecret(MasterSecret masterSecret) {
this.masterSecret = masterSecret;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
View layout = inflater.inflate(R.layout.export_fragment, container, false);
// View exportEncryptedView = layout.findViewById(R.id.export_encrypted_backup);
View exportPlaintextView = layout.findViewById(R.id.export_plaintext_backup);
// exportEncryptedView.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// handleExportEncryptedBackup();
// }
// });
exportPlaintextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleExportPlaintextBackup();
}
});
return layout;
}
// private void handleExportEncryptedBackup() {
// AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// builder.setIcon(Dialogs.getDrawable(getActivity(), R.attr.dialog_info_icon));
// builder.setTitle(getActivity().getString(R.string.ExportFragment_export_to_sd_card));
// builder.setMessage(getActivity().getString(R.string.ExportFragment_this_will_export_your_encrypted_keys_settings_and_messages));
// builder.setPositiveButton(getActivity().getString(R.string.ExportFragment_export), new Dialog.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialog, int which) {
// new ExportEncryptedTask().execute();
// }
// });
// builder.setNegativeButton(getActivity().getString(R.string.ExportFragment_cancel), null);
// builder.show();
// }
private void handleExportPlaintextBackup() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setIconAttribute(R.attr.dialog_alert_icon);
builder.setTitle(getActivity().getString(R.string.ExportFragment_export_plaintext_to_storage));
builder.setMessage(getActivity().getString(R.string.ExportFragment_warning_this_will_export_the_plaintext_contents));
builder.setPositiveButton(getActivity().getString(R.string.ExportFragment_export), new Dialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new ExportPlaintextTask().execute();
}
});
builder.setNegativeButton(getActivity().getString(R.string.ExportFragment_cancel), null);
builder.show();
}
private class ExportPlaintextTask extends AsyncTask<Void, Void, Integer> {
private ProgressDialog dialog;
@Override
protected void onPreExecute() {
dialog = ProgressDialog.show(getActivity(),
getActivity().getString(R.string.ExportFragment_exporting),
getActivity().getString(R.string.ExportFragment_exporting_plaintext_to_storage),
true, false);
}
@Override
protected Integer doInBackground(Void... params) {
try {
PlaintextBackupExporter.exportPlaintextToSd(getActivity(), masterSecret);
return SUCCESS;
} catch (NoExternalStorageException e) {
Log.w("ExportFragment", e);
return NO_SD_CARD;
} catch (IOException e) {
Log.w("ExportFragment", e);
return IO_ERROR;
}
}
@Override
protected void onPostExecute(Integer result) {
Context context = getActivity();
if (dialog != null)
dialog.dismiss();
if (context == null)
return;
switch (result) {
case NO_SD_CARD:
Toast.makeText(context,
context.getString(R.string.ExportFragment_error_unable_to_write_to_storage),
Toast.LENGTH_LONG).show();
break;
case IO_ERROR:
Toast.makeText(context,
context.getString(R.string.ExportFragment_error_while_writing_to_storage),
Toast.LENGTH_LONG).show();
break;
case SUCCESS:
Toast.makeText(context,
context.getString(R.string.ExportFragment_export_successful),
Toast.LENGTH_LONG).show();
break;
}
}
}
// private class ExportEncryptedTask extends AsyncTask<Void, Void, Integer> {
// private ProgressDialog dialog;
//
// @Override
// protected void onPreExecute() {
// dialog = ProgressDialog.show(getActivity(),
// getActivity().getString(R.string.ExportFragment_exporting),
// getActivity().getString(R.string.ExportFragment_exporting_keys_settings_and_messages),
// true, false);
// }
//
// @Override
// protected void onPostExecute(Integer result) {
// Context context = getActivity();
//
// if (dialog != null) dialog.dismiss();
//
// if (context == null) return;
//
// switch (result) {
// case NO_SD_CARD:
// Toast.makeText(context,
// context.getString(R.string.ExportFragment_error_unable_to_write_to_storage),
// Toast.LENGTH_LONG).show();
// break;
// case IO_ERROR:
// Toast.makeText(context,
// context.getString(R.string.ExportFragment_error_while_writing_to_storage),
// Toast.LENGTH_LONG).show();
// break;
// case SUCCESS:
// Toast.makeText(context,
// context.getString(R.string.ExportFragment_success),
// Toast.LENGTH_LONG).show();
// break;
// }
// }
//
// @Override
// protected Integer doInBackground(Void... params) {
// try {
// EncryptedBackupExporter.exportToSd(getActivity());
// return SUCCESS;
// } catch (NoExternalStorageException e) {
// Log.w("ExportFragment", e);
// return NO_SD_CARD;
// } catch (IOException e) {
// Log.w("ExportFragment", e);
// return IO_ERROR;
// }
// }
// }
}

View File

@ -2,25 +2,17 @@ package org.thoughtcrime.securesms;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.view.MenuItem; import android.view.MenuItem;
import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.DynamicTheme;
public class ImportExportActivity extends PassphraseRequiredActionBarActivity { public class ImportExportActivity extends PassphraseRequiredActionBarActivity {
private MasterSecret masterSecret; private DynamicTheme dynamicTheme = new DynamicTheme();
private TabPagerAdapter tabPagerAdapter; private DynamicLanguage dynamicLanguage = new DynamicLanguage();
private ViewPager viewPager;
private DynamicTheme dynamicTheme = new DynamicTheme();
@Override @Override
protected void onPreCreate() { protected void onPreCreate() {
@ -29,19 +21,15 @@ public class ImportExportActivity extends PassphraseRequiredActionBarActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState, @NonNull MasterSecret masterSecret) { protected void onCreate(Bundle savedInstanceState, @NonNull MasterSecret masterSecret) {
this.masterSecret = masterSecret;
setContentView(R.layout.import_export_activity);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
initFragment(android.R.id.content, new ImportExportFragment(),
initializeResources(); masterSecret, dynamicLanguage.getCurrentLocale());
initializeViewPager();
initializeTabs();
} }
@Override @Override
public void onResume() { public void onResume() {
dynamicTheme.onResume(this); dynamicTheme.onResume(this);
super.onResume(); super.onResume();
} }
@Override @Override
@ -54,70 +42,4 @@ public class ImportExportActivity extends PassphraseRequiredActionBarActivity {
return false; return false;
} }
private void initializeResources() {
this.viewPager = (ViewPager) findViewById(R.id.import_export_pager);
this.tabPagerAdapter = new TabPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(tabPagerAdapter);
}
private void initializeViewPager() {
viewPager.setAdapter(tabPagerAdapter);
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
getSupportActionBar().setSelectedNavigationItem(position);
}
});
}
private void initializeTabs() {
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {}
};
actionBar.addTab(actionBar.newTab().setText(R.string.ImportExportActivity_import).setTabListener(tabListener));
actionBar.addTab(actionBar.newTab().setText(R.string.ImportExportActivity_export).setTabListener(tabListener));
}
private class TabPagerAdapter extends FragmentStatePagerAdapter {
private final ImportFragment importFragment;
private final ExportFragment exportFragment;
public TabPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
this.importFragment = new ImportFragment();
this.exportFragment = new ExportFragment();
this.importFragment.setMasterSecret(masterSecret);
this.exportFragment.setMasterSecret(masterSecret);
}
@Override
public Fragment getItem(int i) {
if (i == 0) return importFragment;
else return exportFragment;
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int i) {
if (i == 0) return getString(R.string.ImportExportActivity_import);
else return getString(R.string.ImportExportActivity_export);
}
}
} }

View File

@ -1,5 +1,6 @@
package org.thoughtcrime.securesms; package org.thoughtcrime.securesms;
import android.app.Dialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -15,35 +16,35 @@ import android.view.ViewGroup;
import android.widget.Toast; import android.widget.Toast;
import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.EncryptedBackupExporter;
import org.thoughtcrime.securesms.database.NoExternalStorageException; import org.thoughtcrime.securesms.database.NoExternalStorageException;
import org.thoughtcrime.securesms.database.PlaintextBackupExporter;
import org.thoughtcrime.securesms.database.PlaintextBackupImporter; import org.thoughtcrime.securesms.database.PlaintextBackupImporter;
import org.thoughtcrime.securesms.service.ApplicationMigrationService; import org.thoughtcrime.securesms.service.ApplicationMigrationService;
import org.thoughtcrime.securesms.service.KeyCachingService;
import java.io.IOException; import java.io.IOException;
public class ImportFragment extends Fragment { public class ImportExportFragment extends Fragment {
private static final int SUCCESS = 0; private static final int SUCCESS = 0;
private static final int NO_SD_CARD = 1; private static final int NO_SD_CARD = 1;
private static final int ERROR_IO = 2; private static final int ERROR_IO = 2;
private MasterSecret masterSecret; private MasterSecret masterSecret;
private ProgressDialog progressDialog; private ProgressDialog progressDialog;
public void setMasterSecret(MasterSecret masterSecret) { @Override
this.masterSecret = masterSecret; public void onCreate(Bundle bundle) {
super.onCreate(bundle);
this.masterSecret = getArguments().getParcelable("master_secret");
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
View layout = inflater.inflate(R.layout.import_fragment, container, false); View layout = inflater.inflate(R.layout.import_export_fragment, container, false);
View importSmsView = layout.findViewById(R.id.import_sms ); View importSmsView = layout.findViewById(R.id.import_sms );
View importEncryptedView = layout.findViewById(R.id.import_encrypted_backup);
View importPlaintextView = layout.findViewById(R.id.import_plaintext_backup); View importPlaintextView = layout.findViewById(R.id.import_plaintext_backup);
View exportPlaintextView = layout.findViewById(R.id.export_plaintext_backup);
importSmsView.setOnClickListener(new View.OnClickListener() { importSmsView.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -52,13 +53,6 @@ public class ImportFragment extends Fragment {
} }
}); });
importEncryptedView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleImportEncryptedBackup();
}
});
importPlaintextView.setOnClickListener(new View.OnClickListener() { importPlaintextView.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -66,6 +60,13 @@ public class ImportFragment extends Fragment {
} }
}); });
exportPlaintextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleExportPlaintextBackup();
}
});
return layout; return layout;
} }
@ -103,21 +104,6 @@ public class ImportFragment extends Fragment {
builder.show(); builder.show();
} }
private void handleImportEncryptedBackup() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setIconAttribute(R.attr.dialog_alert_icon);
builder.setTitle(getActivity().getString(R.string.ImportFragment_restore_encrypted_backup));
builder.setMessage(getActivity().getString(R.string.ImportFragment_restoring_an_encrypted_backup_will_completely_replace_your_existing_keys));
builder.setPositiveButton(getActivity().getString(R.string.ImportFragment_restore), new AlertDialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new ImportEncryptedBackupTask().execute();
}
});
builder.setNegativeButton(getActivity().getString(R.string.ImportFragment_cancel), null);
builder.show();
}
private void handleImportPlaintextBackup() { private void handleImportPlaintextBackup() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setIconAttribute(R.attr.dialog_alert_icon); builder.setIconAttribute(R.attr.dialog_alert_icon);
@ -133,6 +119,21 @@ public class ImportFragment extends Fragment {
builder.show(); builder.show();
} }
private void handleExportPlaintextBackup() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setIconAttribute(R.attr.dialog_alert_icon);
builder.setTitle(getActivity().getString(R.string.ExportFragment_export_plaintext_to_storage));
builder.setMessage(getActivity().getString(R.string.ExportFragment_warning_this_will_export_the_plaintext_contents));
builder.setPositiveButton(getActivity().getString(R.string.ExportFragment_export), new Dialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new ExportPlaintextTask().execute();
}
});
builder.setNegativeButton(getActivity().getString(R.string.ExportFragment_cancel), null);
builder.show();
}
private class ImportPlaintextBackupTask extends AsyncTask<Void, Void, Integer> { private class ImportPlaintextBackupTask extends AsyncTask<Void, Void, Integer> {
@Override @Override
@ -184,23 +185,39 @@ public class ImportFragment extends Fragment {
return ERROR_IO; return ERROR_IO;
} }
} }
} }
private class ImportEncryptedBackupTask extends AsyncTask<Void, Void, Integer> { private class ExportPlaintextTask extends AsyncTask<Void, Void, Integer> {
private ProgressDialog dialog;
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
progressDialog = ProgressDialog.show(getActivity(), dialog = ProgressDialog.show(getActivity(),
getActivity().getString(R.string.ImportFragment_restoring), getActivity().getString(R.string.ExportFragment_exporting),
getActivity().getString(R.string.ImportFragment_restoring_encrypted_backup), getActivity().getString(R.string.ExportFragment_exporting_plaintext_to_storage),
true, false); true, false);
} }
@Override
protected Integer doInBackground(Void... params) {
try {
PlaintextBackupExporter.exportPlaintextToSd(getActivity(), masterSecret);
return SUCCESS;
} catch (NoExternalStorageException e) {
Log.w("ExportFragment", e);
return NO_SD_CARD;
} catch (IOException e) {
Log.w("ExportFragment", e);
return ERROR_IO;
}
}
@Override
protected void onPostExecute(Integer result) { protected void onPostExecute(Integer result) {
Context context = getActivity(); Context context = getActivity();
if (progressDialog != null) if (dialog != null)
progressDialog.dismiss(); dialog.dismiss();
if (context == null) if (context == null)
return; return;
@ -208,39 +225,22 @@ public class ImportFragment extends Fragment {
switch (result) { switch (result) {
case NO_SD_CARD: case NO_SD_CARD:
Toast.makeText(context, Toast.makeText(context,
context.getString(R.string.ImportFragment_no_encrypted_backup_found), context.getString(R.string.ExportFragment_error_unable_to_write_to_storage),
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG).show();
break; break;
case ERROR_IO: case ERROR_IO:
Toast.makeText(context, Toast.makeText(context,
context.getString(R.string.ImportFragment_error_importing_backup), context.getString(R.string.ExportFragment_error_while_writing_to_storage),
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG).show();
break; break;
case SUCCESS: case SUCCESS:
DatabaseFactory.getInstance(context).reset(context);
Intent intent = new Intent(context, KeyCachingService.class);
intent.setAction(KeyCachingService.CLEAR_KEY_ACTION);
context.startService(intent);
Toast.makeText(context, Toast.makeText(context,
context.getString(R.string.ImportFragment_restore_complete), context.getString(R.string.ExportFragment_export_successful),
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG).show();
} break;
}
@Override
protected Integer doInBackground(Void... params) {
try {
EncryptedBackupExporter.importFromSd(getActivity());
return SUCCESS;
} catch (NoExternalStorageException e) {
Log.w("ImportFragment", e);
return NO_SD_CARD;
} catch (IOException e) {
Log.w("ImportFragment", e);
return ERROR_IO;
} }
} }
} }
} }