From b95bdbe791a8b7609b46ec5b9c089b2dc2461314 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Mon, 26 Feb 2018 19:38:19 +0100 Subject: implement multi accounts via expert settings --- src/main/java/de/pixart/messenger/Config.java | 1 - .../messenger/services/ExportLogsService.java | 30 ++++- .../messenger/services/NotificationService.java | 19 ++-- .../messenger/services/XmppConnectionService.java | 4 + .../pixart/messenger/ui/ConversationActivity.java | 9 +- .../pixart/messenger/ui/ManageAccountActivity.java | 5 - .../de/pixart/messenger/ui/SettingsActivity.java | 122 +++++++++++++++++++-- .../de/pixart/messenger/ui/SettingsFragment.java | 1 - .../messenger/ui/StartConversationActivity.java | 6 + .../java/de/pixart/messenger/ui/XmppActivity.java | 15 ++- src/main/res/layout/password.xml | 12 +- src/main/res/menu/change_presence.xml | 5 - src/main/res/menu/verify_otr.xml | 5 - src/main/res/values/defaults.xml | 1 + src/main/res/values/strings.xml | 2 + src/main/res/xml/preferences.xml | 5 + 16 files changed, 201 insertions(+), 41 deletions(-) diff --git a/src/main/java/de/pixart/messenger/Config.java b/src/main/java/de/pixart/messenger/Config.java index 67577be03..5a9236d53 100644 --- a/src/main/java/de/pixart/messenger/Config.java +++ b/src/main/java/de/pixart/messenger/Config.java @@ -47,7 +47,6 @@ public final class Config { public static final Integer[] XMPP_Ports = null; //BuildConfig.XMPP_Ports; // set to null means disable public static final String DOMAIN_LOCK = null; //BuildConfig.DOMAIN_LOCK; //only allow account creation for this domain public static final String MAGIC_CREATE_DOMAIN = "pix-art.de"; - public static final boolean SINGLE_ACCOUNT = true; //set to true to allow only one account public static final boolean DISALLOW_REGISTRATION_IN_UI = false; //hide the register checkbox public static final boolean ALLOW_NON_TLS_CONNECTIONS = false; //very dangerous. you should have a good reason to set this to true diff --git a/src/main/java/de/pixart/messenger/services/ExportLogsService.java b/src/main/java/de/pixart/messenger/services/ExportLogsService.java index 2337d04d0..63ac1be68 100644 --- a/src/main/java/de/pixart/messenger/services/ExportLogsService.java +++ b/src/main/java/de/pixart/messenger/services/ExportLogsService.java @@ -9,6 +9,7 @@ import android.os.IBinder; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.preference.PreferenceManager; +import android.support.annotation.BoolRes; import android.support.v4.app.NotificationCompat; import android.util.Log; @@ -37,6 +38,8 @@ import de.pixart.messenger.persistance.FileBackend; import de.pixart.messenger.utils.EncryptDecryptFile; import de.pixart.messenger.xmpp.jid.Jid; +import static de.pixart.messenger.ui.SettingsActivity.USE_MULTI_ACCOUNTS; + public class ExportLogsService extends Service { private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); @@ -49,6 +52,7 @@ public class ExportLogsService extends Service { boolean ReadableLogsEnabled = false; private WakeLock wakeLock; private PowerManager pm; + XmppConnectionService mXmppConnectionService; @Override public void onCreate() { @@ -178,6 +182,7 @@ public class ExportLogsService extends Service { public void ExportDatabase() throws IOException { Account mAccount = mAccounts.get(0); + String EncryptionKey = null; // Get hold of the db: FileInputStream InputFile = new FileInputStream(this.getDatabasePath(DatabaseBackend.DATABASE_NAME)); // Set the output folder on the SDcard @@ -195,7 +200,18 @@ public class ExportLogsService extends Service { // Set the output file stream up: FileOutputStream OutputFile = new FileOutputStream(directory.getPath() + "/database.db.crypt"); - String EncryptionKey = mAccount.getPassword(); //get account password + if (mAccounts.size() == 1 && !multipleAccounts()) { + EncryptionKey = mAccount.getPassword(); //get account password + } else { + SharedPreferences multiaccount_prefs = getApplicationContext().getSharedPreferences(USE_MULTI_ACCOUNTS, Context.MODE_PRIVATE); + String password = multiaccount_prefs.getString("BackupPW", null); + if (password == null) { + Log.d(Config.LOGTAG, "Database exporter: failed to write encryted backup to sdcard because of missing password"); + return; + } + EncryptionKey = password; //get previously set backup password + } + Log.d(Config.LOGTAG, "Database exporter: encrypt backup with password " + EncryptionKey); // encrypt database from the input file to the output file try { @@ -216,4 +232,16 @@ public class ExportLogsService extends Service { public IBinder onBind(Intent intent) { return null; } + + public SharedPreferences getPreferences() { + return PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + } + + public boolean getBooleanPreference(String name, @BoolRes int res) { + return getPreferences().getBoolean(name, getResources().getBoolean(res)); + } + + public boolean multipleAccounts() { + return getBooleanPreference("enable_multi_accounts", R.bool.confirm_messages); + } } diff --git a/src/main/java/de/pixart/messenger/services/NotificationService.java b/src/main/java/de/pixart/messenger/services/NotificationService.java index 7ce896814..ba4b3dc4e 100644 --- a/src/main/java/de/pixart/messenger/services/NotificationService.java +++ b/src/main/java/de/pixart/messenger/services/NotificationService.java @@ -745,20 +745,23 @@ public class NotificationService { String status; Account mAccount = null; Log.d(Config.LOGTAG, "Accounts size " + accounts.size()); - if (accounts.size() > 0) { + if (accounts.size() == 1) { mAccount = accounts.get(0); if (mAccount.getStatus() == Account.State.ONLINE) { - status = mXmppConnectionService.getString(R.string.account_status_online); + status = "(" + mXmppConnectionService.getString(R.string.account_status_online) + ")"; } else if (mAccount.getStatus() == Account.State.CONNECTING) { - status = mXmppConnectionService.getString(R.string.account_status_connecting); + status = "(" + mXmppConnectionService.getString(R.string.account_status_connecting) + ")"; } else { - status = mXmppConnectionService.getString(R.string.account_status_offline); + status = "(" + mXmppConnectionService.getString(R.string.account_status_offline) + ")"; } + } else if (accounts.size() > 1) { + status = ""; // todo: status for multiple accounts??? } else { - status = mXmppConnectionService.getString(R.string.account_status_offline); + status = "(" + mXmppConnectionService.getString(R.string.account_status_offline) + ")"; } + status = " " + status; Log.d(Config.LOGTAG, "Status: " + status); - mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.conversations_foreground_service) + " (" + status + ")"); + mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.conversations_foreground_service) + status); if (Config.SHOW_CONNECTED_ACCOUNTS) { int enabled = 0; int connected = 0; @@ -777,8 +780,10 @@ public class NotificationService { mBuilder.setContentIntent(createOpenConversationsIntent()); mBuilder.setWhen(0); mBuilder.setPriority(Config.SHOW_CONNECTED_ACCOUNTS ? NotificationCompat.PRIORITY_DEFAULT : NotificationCompat.PRIORITY_MIN); - if (accounts.size() > 0 && mAccount.getStatus() == Account.State.ONLINE) { + if (accounts.size() == 1 && accounts.get(0).getStatus() == Account.State.ONLINE) { mBuilder.setSmallIcon(R.drawable.ic_link_white_24dp); + } else if (accounts.size() > 1) { + mBuilder.setSmallIcon(R.drawable.ic_link_white_24dp); // todo: status for multiple accounts??? } else { mBuilder.setSmallIcon(R.drawable.ic_unlink_white_24dp); } diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java index ad802711c..d26114b47 100644 --- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java +++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java @@ -3560,6 +3560,10 @@ public class XmppConnectionService extends Service { return getBooleanPreference(SettingsActivity.BROADCAST_LAST_ACTIVITY, R.bool.last_activity); } + public boolean multipleAccounts() { + return getBooleanPreference("enable_multi_accounts", R.bool.enable_multi_accounts); + } + public int unreadCount() { int count = 0; for (Conversation conversation : getConversations()) { diff --git a/src/main/java/de/pixart/messenger/ui/ConversationActivity.java b/src/main/java/de/pixart/messenger/ui/ConversationActivity.java index 32398d8ed..192979083 100644 --- a/src/main/java/de/pixart/messenger/ui/ConversationActivity.java +++ b/src/main/java/de/pixart/messenger/ui/ConversationActivity.java @@ -484,7 +484,14 @@ public class ConversationActivity extends XmppActivity final MenuItem menuUpdater = menu.findItem(R.id.action_check_updates); final MenuItem menuInviteUser = menu.findItem(R.id.action_invite_user); final MenuItem menuSearchHistory = menu.findItem(R.id.action_search_history); - + final MenuItem menuActionAccounts = menu.findItem(R.id.action_accounts); + if (xmppConnectionServiceBound) { + if (xmppConnectionService.getAccounts().size() == 1 && !xmppConnectionService.multipleAccounts()) { + menuActionAccounts.setTitle(R.string.mgmt_account_edit); + } else { + menuActionAccounts.setTitle(R.string.action_accounts); + } + } if (isConversationsOverviewVisable() && isConversationsOverviewHideable()) { menuArchiveChat.setVisible(false); menuArchiveMuc.setVisible(false); diff --git a/src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java b/src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java index b253d4021..2d0d98ce7 100644 --- a/src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java +++ b/src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java @@ -3,8 +3,6 @@ package de.pixart.messenger.ui; import android.app.ActionBar; import android.app.AlertDialog; import android.content.ActivityNotFoundException; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; import android.security.KeyChain; @@ -164,10 +162,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda if (Config.X509_VERIFICATION) { addAccount.setVisible(false); addAccountWithCertificate.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - } else { - addAccount.setVisible(!Config.SINGLE_ACCOUNT); } - addAccountWithCertificate.setVisible(!Config.SINGLE_ACCOUNT); return true; } diff --git a/src/main/java/de/pixart/messenger/ui/SettingsActivity.java b/src/main/java/de/pixart/messenger/ui/SettingsActivity.java index 0ee32de09..988f4be1e 100644 --- a/src/main/java/de/pixart/messenger/ui/SettingsActivity.java +++ b/src/main/java/de/pixart/messenger/ui/SettingsActivity.java @@ -2,6 +2,7 @@ package de.pixart.messenger.ui; import android.app.AlertDialog; import android.app.FragmentManager; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; @@ -9,11 +10,16 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; +import android.preference.CheckBoxPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceCategory; import android.preference.PreferenceManager; import android.preference.PreferenceScreen; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.EditText; import android.widget.Toast; import java.security.KeyStoreException; @@ -24,7 +30,6 @@ import java.util.List; import java.util.Locale; import de.duenndns.ssl.MemorizingTrustManager; -import de.pixart.messenger.BuildConfig; import de.pixart.messenger.Config; import de.pixart.messenger.R; import de.pixart.messenger.entities.Account; @@ -48,10 +53,14 @@ public class SettingsActivity extends XmppActivity implements public static final String SHOW_DYNAMIC_TAGS = "show_dynamic_tags"; public static final String SHOW_FOREGROUND_SERVICE = "show_foreground_service"; public static final String USE_BUNDLED_EMOJIS = "use_bundled_emoji"; + public static final String USE_MULTI_ACCOUNTS = "use_multi_accounts"; public static final int REQUEST_WRITE_LOGS = 0xbf8701; private SettingsFragment mSettingsFragment; + Preference multiAccountPreference; + boolean isMultiAccountChecked = false; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -72,6 +81,10 @@ public class SettingsActivity extends XmppActivity implements public void onStart() { super.onStart(); PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this); + + multiAccountPreference = mSettingsFragment.findPreference("enable_multi_accounts"); + isMultiAccountChecked = ((CheckBoxPreference) multiAccountPreference).isChecked(); + ListPreference resources = (ListPreference) mSettingsFragment.findPreference("resource"); if (resources != null) { ArrayList entries = new ArrayList<>(Arrays.asList(resources.getEntries())); @@ -101,13 +114,10 @@ public class SettingsActivity extends XmppActivity implements } } - - if (BuildConfig.FLAVOR != "open") { - PreferenceCategory connectionOptions = (PreferenceCategory) mSettingsFragment.findPreference("connection_options"); - PreferenceScreen expert = (PreferenceScreen) mSettingsFragment.findPreference("expert"); - if (connectionOptions != null) { - expert.removePreference(connectionOptions); - } + PreferenceCategory connectionOptions = (PreferenceCategory) mSettingsFragment.findPreference("connection_options"); + PreferenceScreen expert = (PreferenceScreen) mSettingsFragment.findPreference("expert"); + if (connectionOptions != null) { + expert.removePreference(connectionOptions); } final Preference removeCertsPreference = mSettingsFragment.findPreference("remove_trusted_certificates"); @@ -191,6 +201,33 @@ public class SettingsActivity extends XmppActivity implements return true; } }); + + final Preference enableMultiAccountsPreference = mSettingsFragment.findPreference("enable_multi_accounts"); + Log.d(Config.LOGTAG, "Multi account checkbox checked: " + isMultiAccountChecked); + if (isMultiAccountChecked) { + enableMultiAccountsPreference.setEnabled(false); + /* + if (xmppConnectionServiceBound) { // todo doesn't work --> it seems the service is never bound + final List accounts = xmppConnectionService.getAccounts(); + Log.d(Config.LOGTAG, "Disabled multi account: Number of accounts " + accounts.size()); + if (accounts.size() > 1) { + Log.d(Config.LOGTAG, "Disabled multi account not possible because you have more than one account"); + enableMultiAccountsPreference.setEnabled(false); + } else { + Log.d(Config.LOGTAG, "Disabled multi account possible because you have one account"); + enableMultiAccountsPreference.setEnabled(true); + } + } else { + enableMultiAccountsPreference.setEnabled(false); + } + */ + } else { + enableMultiAccountsPreference.setEnabled(true); + enableMultiAccountsPreference.setOnPreferenceClickListener(preference -> { + enableMultiAccounts(); + return true; + }); + } } private boolean isCallable(final Intent i) { @@ -246,6 +283,75 @@ public class SettingsActivity extends XmppActivity implements dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false); } + private void enableMultiAccounts() { + if (!isMultiAccountChecked) { + multiAccountPreference.setEnabled(true); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setCancelable(false); + builder.setTitle(R.string.pref_enable_multi_accounts_title); + builder.setMessage(R.string.pref_enable_multi_accounts_summary); + builder.setNegativeButton(R.string.cancel, (dialog, which) -> { + ((CheckBoxPreference) multiAccountPreference).setChecked(false); + }); + builder.setPositiveButton(R.string.enter_password, (dialog, which) -> { + ((CheckBoxPreference) multiAccountPreference).setChecked(false); + enterPasswordDialog(); + }); + AlertDialog dialog = builder.create(); + dialog.show(); + } + } + + public void enterPasswordDialog() { + LayoutInflater li = LayoutInflater.from(this); + View promptsView = li.inflate(R.layout.password, null); + + final Preference preference = mSettingsFragment.findPreference("enable_multi_accounts"); + + final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); + alertDialogBuilder.setView(promptsView); + final EditText password = promptsView.findViewById(R.id.password); + final EditText confirm_password = promptsView.findViewById(R.id.confirm_password); + confirm_password.setVisibility(View.VISIBLE); + alertDialogBuilder.setTitle(R.string.enter_password); + alertDialogBuilder.setMessage(R.string.enter_password); + alertDialogBuilder + .setCancelable(false) + .setPositiveButton(R.string.ok, + (dialog, id) -> { + final String pw1 = password.getText().toString(); + final String pw2 = confirm_password.getText().toString(); + if (!pw1.equals(pw2)) { + ((CheckBoxPreference) preference).setChecked(false); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.error); + builder.setMessage(R.string.passwords_do_not_match); + builder.setNegativeButton(R.string.cancel, null); + builder.setPositiveButton(R.string.try_again, (dialog12, id12) -> enterPasswordDialog()); + builder.create().show(); + } else if (pw1.trim().isEmpty()) { + ((CheckBoxPreference) preference).setChecked(false); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.error); + builder.setMessage(R.string.password_should_not_be_empty); + builder.setNegativeButton(R.string.cancel, null); + builder.setPositiveButton(R.string.try_again, (dialog1, id1) -> enterPasswordDialog()); + builder.create().show(); + } else { + ((CheckBoxPreference) preference).setChecked(true); + SharedPreferences multiaccount_prefs = getApplicationContext().getSharedPreferences(USE_MULTI_ACCOUNTS, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = multiaccount_prefs.edit(); + editor.putString("BackupPW", pw1); + editor.commit(); + } + }) + .setNegativeButton(R.string.cancel, null); + alertDialogBuilder.create().show(); + + } + + + @Override public void onStop() { super.onStop(); diff --git a/src/main/java/de/pixart/messenger/ui/SettingsFragment.java b/src/main/java/de/pixart/messenger/ui/SettingsFragment.java index ea9ce7371..8cea5eb61 100644 --- a/src/main/java/de/pixart/messenger/ui/SettingsFragment.java +++ b/src/main/java/de/pixart/messenger/ui/SettingsFragment.java @@ -49,7 +49,6 @@ public class SettingsFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preferences); } diff --git a/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java b/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java index cf6b89aab..c1cd8a015 100644 --- a/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java +++ b/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java @@ -598,6 +598,12 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU MenuItem menuCreateContact = menu.findItem(R.id.action_create_contact); MenuItem menuCreateConference = menu.findItem(R.id.action_conference); MenuItem menuHideOffline = menu.findItem(R.id.action_hide_offline); + final MenuItem menuActionAccounts = menu.findItem(R.id.action_accounts); + if (xmppConnectionService.getAccounts().size() == 1 && !xmppConnectionService.multipleAccounts()) { + menuActionAccounts.setTitle(R.string.mgmt_account_edit); + } else { + menuActionAccounts.setTitle(R.string.action_accounts); + } menuHideOffline.setChecked(this.mHideOfflineContacts); mMenuSearchView = menu.findItem(R.id.action_search); mMenuSearchView.setOnActionExpandListener(mOnActionExpandListener); diff --git a/src/main/java/de/pixart/messenger/ui/XmppActivity.java b/src/main/java/de/pixart/messenger/ui/XmppActivity.java index fa6a2d739..79f528f93 100644 --- a/src/main/java/de/pixart/messenger/ui/XmppActivity.java +++ b/src/main/java/de/pixart/messenger/ui/XmppActivity.java @@ -396,11 +396,16 @@ public abstract class XmppActivity extends Activity { } break; case R.id.action_accounts: - final Intent intent = new Intent(getApplicationContext(), EditAccountActivity.class); - Account mAccount = xmppConnectionService.getAccounts().get(0); - intent.putExtra("jid", mAccount.getJid().toBareJid().toString()); - intent.putExtra("init", false); - startActivity(intent); + if (xmppConnectionService.getAccounts().size() == 1 && !xmppConnectionService.multipleAccounts()) { + final Intent intent = new Intent(getApplicationContext(), EditAccountActivity.class); + Account mAccount = xmppConnectionService.getAccounts().get(0); + intent.putExtra("jid", mAccount.getJid().toBareJid().toString()); + intent.putExtra("init", false); + startActivity(intent); + } else { + final Intent intent = new Intent(getApplicationContext(), ManageAccountActivity.class); + startActivity(intent); + } break; case android.R.id.home: finish(); diff --git a/src/main/res/layout/password.xml b/src/main/res/layout/password.xml index db8d82505..2037f3787 100644 --- a/src/main/res/layout/password.xml +++ b/src/main/res/layout/password.xml @@ -5,9 +5,17 @@ android:layout_height="match_parent"> + android:inputType="textPassword" /> + + \ No newline at end of file diff --git a/src/main/res/menu/change_presence.xml b/src/main/res/menu/change_presence.xml index 1a320d59e..34af0a679 100644 --- a/src/main/res/menu/change_presence.xml +++ b/src/main/res/menu/change_presence.xml @@ -4,11 +4,6 @@ android:title="@string/account_details" android:showAsAction="always" android:icon="@drawable/ic_account_box_white_24dp" /> - - true true true + false diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 4d3cd5162..16fe709ee 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -761,4 +761,6 @@ Snooze Protected Apps To keep receiving notifications, even when the screen is turned off, you need to add Pix-Art Messenger to the list of protected apps. + Enable multiple accounts + You want to use multiple accounts, so you have to set a password for daily backups. diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml index 109d61239..0343d1171 100644 --- a/src/main/res/xml/preferences.xml +++ b/src/main/res/xml/preferences.xml @@ -269,6 +269,11 @@ android:targetClass="com.huawei.systemmanager.optimize.process.ProtectActivity" android:targetPackage="com.huawei.systemmanager" /> +