aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/pixart/messenger/ui
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2019-01-26 15:07:28 +0100
committerChristian Schneppe <christian@pix-art.de>2019-01-26 15:07:28 +0100
commitf2d502518ea3de673c7f0ebf425f53295f620f2f (patch)
tree2db8f4e334d51b59c35105bc1871b102f4bb34d3 /src/main/java/de/pixart/messenger/ui
parent2773c19c429c4bcb99fd0144cd1b3e2346cab962 (diff)
rework backup & restore
use the implementation from Conversations
Diffstat (limited to 'src/main/java/de/pixart/messenger/ui')
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConversationFragment.java30
-rw-r--r--src/main/java/de/pixart/messenger/ui/EditAccountActivity.java31
-rw-r--r--src/main/java/de/pixart/messenger/ui/ImportBackupActivity.java124
-rw-r--r--src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java36
-rw-r--r--src/main/java/de/pixart/messenger/ui/SettingsActivity.java27
-rw-r--r--src/main/java/de/pixart/messenger/ui/UriHandlerActivity.java2
-rw-r--r--src/main/java/de/pixart/messenger/ui/WelcomeActivity.java311
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java148
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/BackupFileAdapter.java167
9 files changed, 478 insertions, 398 deletions
diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
index d7205506d..4f0486cf7 100644
--- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
+++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
@@ -126,6 +126,9 @@ import rocks.xmpp.addr.Jid;
import static de.pixart.messenger.ui.XmppActivity.EXTRA_ACCOUNT;
import static de.pixart.messenger.ui.XmppActivity.REQUEST_INVITE_TO_CONVERSATION;
import static de.pixart.messenger.ui.util.SoftKeyboardUtils.hideSoftKeyboard;
+import static de.pixart.messenger.utils.PermissionUtils.allGranted;
+import static de.pixart.messenger.utils.PermissionUtils.getFirstDenied;
+import static de.pixart.messenger.utils.PermissionUtils.writeGranted;
import static de.pixart.messenger.xmpp.Patches.ENCRYPTION_EXCEPTIONS;
public class ConversationFragment extends XmppFragment implements EditMessage.KeyboardListener, MessageAdapter.OnContactPictureLongClicked, MessageAdapter.OnContactPictureClicked {
@@ -596,33 +599,6 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
return getConversation(activity, R.id.main_fragment);
}
- private static boolean allGranted(int[] grantResults) {
- for (int grantResult : grantResults) {
- if (grantResult != PackageManager.PERMISSION_GRANTED) {
- return false;
- }
- }
- return true;
- }
-
- private static boolean writeGranted(int[] grantResults, String[] permission) {
- for (int i = 0; i < grantResults.length; ++i) {
- if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission[i])) {
- return grantResults[i] == PackageManager.PERMISSION_GRANTED;
- }
- }
- return false;
- }
-
- private static String getFirstDenied(int[] grantResults, String[] permissions) {
- for (int i = 0; i < grantResults.length; ++i) {
- if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
- return permissions[i];
- }
- }
- return null;
- }
-
private static boolean scrolledToBottom(AbsListView listView) {
final int count = listView.getCount();
if (count == 0) {
diff --git a/src/main/java/de/pixart/messenger/ui/EditAccountActivity.java b/src/main/java/de/pixart/messenger/ui/EditAccountActivity.java
index d04289d22..beddb195d 100644
--- a/src/main/java/de/pixart/messenger/ui/EditAccountActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/EditAccountActivity.java
@@ -16,6 +16,7 @@ import android.preference.PreferenceManager;
import android.provider.Settings;
import android.security.KeyChain;
import android.security.KeyChainAliasCallback;
+import android.support.annotation.NonNull;
import android.support.design.widget.TextInputLayout;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
@@ -82,6 +83,9 @@ import de.pixart.messenger.xmpp.forms.Data;
import de.pixart.messenger.xmpp.pep.Avatar;
import rocks.xmpp.addr.Jid;
+import static de.pixart.messenger.utils.PermissionUtils.allGranted;
+import static de.pixart.messenger.utils.PermissionUtils.writeGranted;
+
public class EditAccountActivity extends OmemoActivity implements OnAccountUpdate, OnUpdateBlocklist,
OnKeyStatusUpdated, OnCaptchaRequested, KeyChainAliasCallback, XmppConnectionService.OnShowErrorToast, XmppConnectionService.OnMamPreferencesFetched {
@@ -90,6 +94,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
private static final int REQUEST_DATA_SAVER = 0xf244;
private static final int REQUEST_CHANGE_STATUS = 0xee11;
private static final int REQUEST_ORBOT = 0xff22;
+ private static final int REQUEST_IMPORT_BACKUP = 0x63fb;
private AlertDialog mCaptchaDialog = null;
private final AtomicBoolean mPendingReconnect = new AtomicBoolean(false);
@@ -825,6 +830,12 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
return false;
}
switch (item.getItemId()) {
+ case R.id.action_import_backup:
+ if (hasStoragePermission(REQUEST_IMPORT_BACKUP)) {
+ startActivity(new Intent(this, ImportBackupActivity.class));
+ }
+ overridePendingTransition(R.animator.fade_in, R.animator.fade_out);
+ break;
case R.id.mgmt_account_reconnect:
XmppConnection connection = mAccount.getXmppConnection();
if (connection != null) {
@@ -1444,6 +1455,26 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
}
@Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
+ if (grantResults.length > 0) {
+ if (allGranted(grantResults)) {
+ switch (requestCode) {
+ case REQUEST_IMPORT_BACKUP:
+ startActivity(new Intent(this, ImportBackupActivity.class));
+ break;
+ }
+ } else {
+ Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
+ }
+ }
+ if (writeGranted(grantResults, permissions)) {
+ if (xmppConnectionService != null) {
+ xmppConnectionService.restartFileObserver();
+ }
+ }
+ }
+
+ @Override
public void OnUpdateBlocklist(Status status) {
if (isFinishing()) {
return;
diff --git a/src/main/java/de/pixart/messenger/ui/ImportBackupActivity.java b/src/main/java/de/pixart/messenger/ui/ImportBackupActivity.java
new file mode 100644
index 000000000..f1c9eea25
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/ui/ImportBackupActivity.java
@@ -0,0 +1,124 @@
+package de.pixart.messenger.ui;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.databinding.DataBindingUtil;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.support.design.widget.Snackbar;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.widget.Toolbar;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.widget.Toast;
+
+import java.util.List;
+
+import de.pixart.messenger.Config;
+import de.pixart.messenger.R;
+import de.pixart.messenger.databinding.ActivityImportBackupBinding;
+import de.pixart.messenger.databinding.DialogEnterPasswordBinding;
+import de.pixart.messenger.services.ImportBackupService;
+import de.pixart.messenger.ui.adapter.BackupFileAdapter;
+
+public class ImportBackupActivity extends ActionBarActivity implements ServiceConnection, ImportBackupService.OnBackupFilesLoaded, BackupFileAdapter.OnItemClickedListener, ImportBackupService.OnBackupProcessed {
+
+ private ActivityImportBackupBinding binding;
+
+ private BackupFileAdapter backupFileAdapter;
+ private ImportBackupService service;
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_import_backup);
+ setSupportActionBar((Toolbar) binding.toolbar);
+ configureActionBar(getSupportActionBar());
+ this.backupFileAdapter = new BackupFileAdapter();
+ this.binding.list.setAdapter(this.backupFileAdapter);
+ this.backupFileAdapter.setOnItemClickedListener(this);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ bindService(new Intent(this, ImportBackupService.class), this, Context.BIND_AUTO_CREATE);
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ if (this.service != null) {
+ this.service.removeOnBackupProcessedListener(this);
+ }
+ unbindService(this);
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ ImportBackupService.ImportBackupServiceBinder binder = (ImportBackupService.ImportBackupServiceBinder) service;
+ this.service = binder.getService();
+ this.service.addOnBackupProcessedListener(this);
+ this.service.loadBackupFiles(this);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ this.service = null;
+ }
+
+ @Override
+ public void onBackupFilesLoaded(final List<ImportBackupService.BackupFile> files) {
+ runOnUiThread(() -> {
+ backupFileAdapter.setFiles(files);
+ });
+ }
+
+ @Override
+ public void onClick(ImportBackupService.BackupFile backupFile) {
+ final DialogEnterPasswordBinding enterPasswordBinding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.dialog_enter_password, null, false);
+ Log.d(Config.LOGTAG, "attempting to import " + backupFile.getFile().getAbsolutePath());
+ enterPasswordBinding.explain.setText(getString(R.string.enter_password_to_restore, backupFile.getHeader().getJid().toString()));
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setView(enterPasswordBinding.getRoot());
+ builder.setTitle(R.string.enter_password);
+ builder.setNegativeButton(R.string.cancel, null);
+ builder.setPositiveButton(R.string.restore, (dialog, which) -> {
+ final String password = enterPasswordBinding.accountPassword.getEditableText().toString();
+ Intent intent = new Intent(this, ImportBackupService.class);
+ intent.putExtra("password", password);
+ intent.putExtra("file", backupFile.getFile().getAbsolutePath());
+ ContextCompat.startForegroundService(this, intent);
+ });
+ builder.setCancelable(false);
+ builder.create().show();
+ }
+
+ @Override
+ public void onBackupRestored() {
+ runOnUiThread(() -> {
+ Intent intent = new Intent(this, StartUI.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ startActivity(intent);
+ finish();
+ });
+ }
+
+ @Override
+ public void onBackupDecryptionFailed() {
+ runOnUiThread(() -> {
+ Snackbar.make(binding.coordinator, R.string.unable_to_decrypt_backup, Snackbar.LENGTH_LONG).show();
+ });
+ }
+
+ @Override
+ public void onBackupRestoreFailed() {
+ runOnUiThread(() -> {
+ Snackbar.make(binding.coordinator, R.string.unable_to_restore_backup, Snackbar.LENGTH_LONG).show();
+ });
+ }
+} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java b/src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java
index 607e2626d..a09a285f2 100644
--- a/src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java
@@ -5,6 +5,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.security.KeyChain;
import android.security.KeyChainAliasCallback;
+import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.util.Pair;
@@ -35,10 +36,15 @@ import de.pixart.messenger.utils.MenuDoubleTabUtil;
import de.pixart.messenger.xmpp.XmppConnection;
import rocks.xmpp.addr.Jid;
+import static de.pixart.messenger.utils.PermissionUtils.allGranted;
+import static de.pixart.messenger.utils.PermissionUtils.writeGranted;
+
public class ManageAccountActivity extends XmppActivity implements OnAccountUpdate, KeyChainAliasCallback, XmppConnectionService.OnAccountCreated, AccountAdapter.OnTglAccountState {
private final String STATE_SELECTED_ACCOUNT = "selected_account";
+ private static final int REQUEST_IMPORT_BACKUP = 0x63fb;
+
protected Account selectedAccount = null;
protected Jid selectedAccountJid = null;
@@ -75,7 +81,6 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_accounts);
-
setSupportActionBar(findViewById(R.id.toolbar));
configureActionBar(getSupportActionBar());
if (savedInstanceState != null) {
@@ -156,6 +161,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
addAccount.setVisible(false);
addAccountWithCertificate.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
+
return true;
}
@@ -187,7 +193,13 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
}
switch (item.getItemId()) {
case R.id.action_add_account:
- startActivity(new Intent(getApplicationContext(), EditAccountActivity.class));
+ startActivity(new Intent(this, EditAccountActivity.class));
+ overridePendingTransition(R.animator.fade_in, R.animator.fade_out);
+ break;
+ case R.id.action_import_backup:
+ if (hasStoragePermission(REQUEST_IMPORT_BACKUP)) {
+ startActivity(new Intent(this, ImportBackupActivity.class));
+ }
overridePendingTransition(R.animator.fade_in, R.animator.fade_out);
break;
case R.id.action_add_account_with_cert:
@@ -200,6 +212,26 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
}
@Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
+ if (grantResults.length > 0) {
+ if (allGranted(grantResults)) {
+ switch (requestCode) {
+ case REQUEST_IMPORT_BACKUP:
+ startActivity(new Intent(this, ImportBackupActivity.class));
+ break;
+ }
+ } else {
+ Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
+ }
+ }
+ if (writeGranted(grantResults, permissions)) {
+ if (xmppConnectionService != null) {
+ xmppConnectionService.restartFileObserver();
+ }
+ }
+ }
+
+ @Override
public boolean onNavigateUp() {
if (xmppConnectionService.getConversations().size() == 0) {
Intent contactsIntent = new Intent(this,
diff --git a/src/main/java/de/pixart/messenger/ui/SettingsActivity.java b/src/main/java/de/pixart/messenger/ui/SettingsActivity.java
index 9c45d01b8..3eb01eb83 100644
--- a/src/main/java/de/pixart/messenger/ui/SettingsActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/SettingsActivity.java
@@ -36,7 +36,8 @@ import de.pixart.messenger.Config;
import de.pixart.messenger.R;
import de.pixart.messenger.crypto.OmemoSetting;
import de.pixart.messenger.entities.Account;
-import de.pixart.messenger.services.ExportLogsService;
+import de.pixart.messenger.persistance.FileBackend;
+import de.pixart.messenger.services.ExportBackupService;
import de.pixart.messenger.services.MemorizingTrustManager;
import de.pixart.messenger.ui.util.StyledAttributes;
import de.pixart.messenger.utils.Compatibility;
@@ -64,7 +65,7 @@ public class SettingsActivity extends XmppActivity implements
public static final String NUMBER_OF_ACCOUNTS = "number_of_accounts";
public static final String PLAY_GIF_INSIDE = "play_gif_inside";
- public static final int REQUEST_WRITE_LOGS = 0xbf8701;
+ public static final int REQUEST_CREATE_BACKUP = 0xbf8701;
Preference multiAccountPreference;
Preference BundledEmojiPreference;
Preference QuickShareAttachmentChoicePreference;
@@ -249,11 +250,12 @@ public class SettingsActivity extends XmppActivity implements
});
}
- final Preference exportLogsPreference = mSettingsFragment.findPreference("export_logs");
- if (exportLogsPreference != null) {
- exportLogsPreference.setOnPreferenceClickListener(preference -> {
- if (hasStoragePermission(REQUEST_WRITE_LOGS)) {
- startExport();
+ final Preference createBackupPreference = mSettingsFragment.findPreference("create_backup");
+ if (createBackupPreference != null) {
+ createBackupPreference.setSummary(getString(R.string.pref_create_backup_summary, FileBackend.getBackupDirectory()));
+ createBackupPreference.setOnPreferenceClickListener(preference -> {
+ if (hasStoragePermission(REQUEST_CREATE_BACKUP)) {
+ createBackup();
}
return true;
});
@@ -538,18 +540,19 @@ public class SettingsActivity extends XmppActivity implements
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- if (grantResults.length > 0)
+ if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- if (requestCode == REQUEST_WRITE_LOGS) {
- startExport();
+ if (requestCode == REQUEST_CREATE_BACKUP) {
+ createBackup();
}
} else {
Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
}
+ }
}
- private void startExport() {
- Compatibility.startService(this, new Intent(this, ExportLogsService.class));
+ private void createBackup() {
+ ContextCompat.startForegroundService(this, new Intent(this, ExportBackupService.class));
}
private void displayToast(final String msg) {
diff --git a/src/main/java/de/pixart/messenger/ui/UriHandlerActivity.java b/src/main/java/de/pixart/messenger/ui/UriHandlerActivity.java
index 559e20648..f5a5fb14f 100644
--- a/src/main/java/de/pixart/messenger/ui/UriHandlerActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/UriHandlerActivity.java
@@ -86,7 +86,7 @@ public class UriHandlerActivity extends AppCompatActivity {
private void handleUri(Uri uri, final boolean scanned) {
final Intent intent;
final XmppUri xmppUri = new XmppUri(uri);
- final List<Jid> accounts = DatabaseBackend.getInstance(this).getAccountJids(); //TODO only look at enabled accounts
+ final List<Jid> accounts = DatabaseBackend.getInstance(this).getAccountJids(true);
if (accounts.size() == 0) {
if (xmppUri.isJidValid()) {
intent = SignupUtils.getSignUpIntent(this);
diff --git a/src/main/java/de/pixart/messenger/ui/WelcomeActivity.java b/src/main/java/de/pixart/messenger/ui/WelcomeActivity.java
index 75493d6c8..0ce07dda4 100644
--- a/src/main/java/de/pixart/messenger/ui/WelcomeActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/WelcomeActivity.java
@@ -10,6 +10,7 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.Build;
import android.os.Bundle;
+import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
@@ -41,9 +42,12 @@ import de.pixart.messenger.persistance.FileBackend;
import de.pixart.messenger.utils.EncryptDecryptFile;
import de.pixart.messenger.utils.XmppUri;
+import static de.pixart.messenger.utils.PermissionUtils.allGranted;
+import static de.pixart.messenger.utils.PermissionUtils.writeGranted;
+
public class WelcomeActivity extends XmppActivity {
- boolean importSuccessful = false;
+ private static final int REQUEST_IMPORT_BACKUP = 0x63fb;
@Override
protected void refreshUiReal() {
@@ -85,21 +89,14 @@ public class WelcomeActivity extends XmppActivity {
ab.setDisplayHomeAsUpEnabled(false);
}
- //check if there is a backed up database --
- if (hasStoragePermission(REQUEST_READ_EXTERNAL_STORAGE)) {
- BackupAvailable();
- }
-
-
final Button ImportDatabase = findViewById(R.id.import_database);
final TextView ImportText = findViewById(R.id.import_text);
-
- if (BackupAvailable() != 0) {
+ if (hasStoragePermission(REQUEST_IMPORT_BACKUP)) {
ImportDatabase.setVisibility(View.VISIBLE);
ImportText.setVisibility(View.VISIBLE);
}
+ ImportDatabase.setOnClickListener(v -> startActivity(new Intent(this, ImportBackupActivity.class)));
- ImportDatabase.setOnClickListener(v -> enterPasswordDialog(BackupAvailable()));
final Button createAccount = findViewById(R.id.create_account);
createAccount.setOnClickListener(v -> {
@@ -127,290 +124,34 @@ public class WelcomeActivity extends XmppActivity {
}
- public void enterPasswordDialog(final int backup_type) {
- if (backup_type == 1) {
- LayoutInflater li = LayoutInflater.from(WelcomeActivity.this);
- View promptsView = li.inflate(R.layout.password, null);
- final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(WelcomeActivity.this);
- alertDialogBuilder.setView(promptsView);
- final EditText userInput = promptsView
- .findViewById(R.id.password);
- alertDialogBuilder.setTitle(R.string.enter_password);
- alertDialogBuilder.setMessage(R.string.enter_account_password);
- alertDialogBuilder
- .setCancelable(false)
- .setPositiveButton(R.string.ok,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- final String password = userInput.getText().toString();
- final ProgressDialog pd = ProgressDialog.show(WelcomeActivity.this, getString(R.string.please_wait), getString(R.string.databaseimport_started), true);
- if (!password.isEmpty()) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- checkDatabase(password);
- } catch (IOException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
- pd.dismiss();
- }
- }).start();
- } else {
- AlertDialog.Builder builder = new AlertDialog.Builder(WelcomeActivity.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, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- enterPasswordDialog(backup_type);
- }
- });
- builder.create().show();
- }
- }
- })
- .setNegativeButton(R.string.cancel,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- Toast.makeText(WelcomeActivity.this, R.string.import_canceled, Toast.LENGTH_LONG).show();
- dialog.dismiss();
- }
- }
- );
- WelcomeActivity.this.runOnUiThread(new Runnable() {
- public void run() {
- // create alert dialog
- AlertDialog alertDialog = alertDialogBuilder.create();
- // show it
- alertDialog.show();
- }
- });
- } else {
- try {
- checkDatabase(null);
- } catch (IOException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
+ public void addInviteUri(Intent intent) {
+ StartConversationActivity.addInviteUri(intent, getIntent());
}
- private int BackupAvailable() {
- // Set the folder on the SDcard
- File filePath_enc = new File(FileBackend.getBackupDirectory() + "/database.db.crypt");
- File filePath_dec = new File(FileBackend.getBackupDirectory() + "/database.db");
- if (filePath_enc.exists()) {
- Log.d(Config.LOGTAG, "DB Path existing (encrypted)");
- return 1;
- } else if (filePath_dec.exists()) {
- Log.d(Config.LOGTAG, "DB Path existing (decrypted)");
- return 2;
- } else {
- Log.d(Config.LOGTAG, "DB Path not existing");
- return 0;
- }
+ public static void launch(AppCompatActivity activity) {
+ Intent intent = new Intent(activity, WelcomeActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ activity.startActivity(intent);
+ activity.overridePendingTransition(0, 0);
}
- private void checkDatabase(String DecryptionKey) throws IOException {
- if (DecryptionKey != null) {
- // Set the folder on the SDcard
- File directory = new File(FileBackend.getBackupDirectory());
- // Set the input file stream up:
- FileInputStream InputFile = new FileInputStream(directory.getPath() + "/database.db.crypt");
- // Temp output for DB checks
- File TempFile = new File(directory.getPath() + "database.bak");
- FileOutputStream OutputTemp = new FileOutputStream(TempFile);
-
- try {
- EncryptDecryptFile.decrypt(InputFile, OutputTemp, DecryptionKey);
- } catch (NoSuchAlgorithmException e) {
- Log.d(Config.LOGTAG, "Database importer: decryption failed with " + e);
- e.printStackTrace();
- } catch (NoSuchPaddingException e) {
- Log.d(Config.LOGTAG, "Database importer: decryption failed with " + e);
- e.printStackTrace();
- } catch (InvalidKeyException e) {
- Log.d(Config.LOGTAG, "Database importer: decryption failed (invalid key) with " + e);
- e.printStackTrace();
- } catch (IOException e) {
- Log.d(Config.LOGTAG, "Database importer: decryption failed (IO) with " + e);
- e.printStackTrace();
- } catch (Exception e) {
- Log.d(Config.LOGTAG, "Database importer: Error " + e);
- e.printStackTrace();
- }
-
- SQLiteDatabase checkDB = null;
- int DB_Version = DatabaseBackend.DATABASE_VERSION;
- int Backup_DB_Version = 0;
-
- try {
- String dbPath = TempFile.toString();
- checkDB = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY);
- Backup_DB_Version = checkDB.getVersion();
- Log.d(Config.LOGTAG, "Backup found: " + checkDB + " Version: " + checkDB.getVersion());
- } catch (SQLiteException e) {
- //database does't exist yet.
- Log.d(Config.LOGTAG, "No backup found: " + checkDB);
- } catch (Exception e) {
- Log.d(Config.LOGTAG, "Error importing backup: " + e);
- }
-
- if (checkDB != null) {
- checkDB.close();
- }
- if (checkDB != null) {
- Log.d(Config.LOGTAG, "checkDB = " + checkDB.toString() + ", Backup DB = " + Backup_DB_Version + ", DB = " + DB_Version);
- }
- if (checkDB != null && Backup_DB_Version != 0 && Backup_DB_Version <= DB_Version) {
- try {
- ImportDatabase();
- importSuccessful = true;
- } catch (Exception e) {
- importSuccessful = false;
- e.printStackTrace();
- } finally {
- if (importSuccessful) {
- restart();
- }
- }
- } else if (checkDB != null && Backup_DB_Version == 0) {
- WelcomeActivity.this.runOnUiThread(new Runnable() {
- public void run() {
- Toast.makeText(WelcomeActivity.this, R.string.Password_wrong, Toast.LENGTH_LONG).show();
- enterPasswordDialog(1);
- }
- });
- } else {
- WelcomeActivity.this.runOnUiThread(new Runnable() {
- public void run() {
- Toast.makeText(WelcomeActivity.this, R.string.Import_failed, Toast.LENGTH_LONG).show();
- }
- });
- }
- } else {
- // Set the folder on the SDcard
- File directory = new File(FileBackend.getBackupDirectory());
- // Set the input file stream up:
- FileInputStream InputFile = new FileInputStream(directory.getPath() + "/database.db");
- // Temp output for DB checks
- File TempFile = new File(directory.getPath() + "database.bak");
- FileOutputStream OutputTemp = new FileOutputStream(TempFile);
-
- try {
- // Transfer bytes from in to out
- byte[] buf = new byte[1024];
- int len;
- while ((len = InputFile.read(buf)) > 0) {
- OutputTemp.write(buf, 0, len);
- }
- } finally {
- OutputTemp.close();
- }
-
- SQLiteDatabase checkDB = null;
- int DB_Version = DatabaseBackend.DATABASE_VERSION;
- int Backup_DB_Version = 0;
-
- try {
- String dbPath = TempFile.toString();
- checkDB = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY);
- Backup_DB_Version = checkDB.getVersion();
- Log.d(Config.LOGTAG, "Backup found: " + checkDB + " Version: " + checkDB.getVersion());
- } catch (SQLiteException e) {
- //database does't exist yet.
- Log.d(Config.LOGTAG, "No backup found: " + checkDB);
- } catch (Exception e) {
- Log.d(Config.LOGTAG, "Error importing backup: " + e);
- }
-
- if (checkDB != null) {
- checkDB.close();
- }
- if (checkDB != null) {
- Log.d(Config.LOGTAG, "checkDB = " + checkDB.toString() + ", Backup DB = " + Backup_DB_Version + ", DB = " + DB_Version);
- }
- if (checkDB != null && Backup_DB_Version != 0 && Backup_DB_Version <= DB_Version) {
- try {
- ImportDatabase();
- importSuccessful = true;
- } catch (Exception e) {
- importSuccessful = false;
- e.printStackTrace();
- } finally {
- if (importSuccessful) {
- restart();
- }
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
+ if (grantResults.length > 0) {
+ if (allGranted(grantResults)) {
+ switch (requestCode) {
+ case REQUEST_IMPORT_BACKUP:
+ startActivity(new Intent(this, ImportBackupActivity.class));
+ break;
}
} else {
- WelcomeActivity.this.runOnUiThread(new Runnable() {
- public void run() {
- Toast.makeText(WelcomeActivity.this, R.string.Import_failed, Toast.LENGTH_LONG).show();
- }
- });
+ Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
}
}
- }
-
- private void ImportDatabase() throws Exception {
- // Set location for the db:
- final OutputStream OutputFile = new FileOutputStream(this.getDatabasePath(DatabaseBackend.DATABASE_NAME));
- // Set the folder on the SDcard
- File directory = new File(FileBackend.getBackupDirectory());
- // Set the input file stream up:
- final InputStream InputFile = new FileInputStream(directory.getPath() + "database.bak");
- //set temp file
- File TempFile = new File(directory.getPath() + "database.bak");
-
- // Transfer bytes from the input file to the output file
- byte[] buffer = new byte[1024];
- int length;
- while ((length = InputFile.read(buffer)) > 0) {
- OutputFile.write(buffer, 0, length);
- }
- if (TempFile.exists()) {
- Log.d(Config.LOGTAG, "Delete temp file from " + TempFile.toString());
- TempFile.delete();
- }
- }
-
- private void restart() {
- //restart app
- Log.d(Config.LOGTAG, "Restarting " + getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName()));
- Intent intent = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(intent);
- overridePendingTransition(R.animator.fade_in, R.animator.fade_out);
- System.exit(0);
- }
-
- public boolean hasStoragePermission(int requestCode) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
- requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, requestCode);
- return false;
- } else {
- return true;
+ if (writeGranted(grantResults, permissions)) {
+ if (xmppConnectionService != null) {
+ xmppConnectionService.restartFileObserver();
}
- } else {
- return true;
}
}
-
- public void addInviteUri(Intent intent) {
- StartConversationActivity.addInviteUri(intent, getIntent());
- }
-
- public static void launch(AppCompatActivity activity) {
- Intent intent = new Intent(activity, WelcomeActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- activity.startActivity(intent);
- activity.overridePendingTransition(0, 0);
- }
} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java
index 391fee0b9..e060d8828 100644
--- a/src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java
+++ b/src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java
@@ -1,19 +1,17 @@
package de.pixart.messenger.ui.adapter;
-import android.content.Context;
import android.content.res.Resources;
+import android.databinding.DataBindingUtil;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
-import android.support.v7.widget.SwitchCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
-import android.widget.TextView;
import java.lang.ref.WeakReference;
import java.util.List;
@@ -21,8 +19,8 @@ import java.util.concurrent.RejectedExecutionException;
import de.pixart.messenger.Config;
import de.pixart.messenger.R;
+import de.pixart.messenger.databinding.AccountRowBinding;
import de.pixart.messenger.entities.Account;
-import de.pixart.messenger.ui.ManageAccountActivity;
import de.pixart.messenger.ui.XmppActivity;
import de.pixart.messenger.ui.util.StyledAttributes;
import de.pixart.messenger.utils.UIHelper;
@@ -44,47 +42,46 @@ public class AccountAdapter extends ArrayAdapter<Account> {
this.showStateButton = true;
}
- @NonNull
@Override
public View getView(int position, View view, @NonNull ViewGroup parent) {
final Account account = getItem(position);
+ final ViewHolder viewHolder;
if (view == null) {
- LayoutInflater inflater = (LayoutInflater) getContext()
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- view = inflater.inflate(R.layout.account_row, parent, false);
+ AccountRowBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.account_row, parent, false);
+ view = binding.getRoot();
+ viewHolder = new ViewHolder(binding);
+ view.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) view.getTag();
}
- TextView jid = view.findViewById(R.id.account_jid);
if (Config.DOMAIN_LOCK != null) {
- jid.setText(account.getJid().getLocal());
+ viewHolder.binding.accountJid.setText(account.getJid().getLocal());
} else {
- jid.setText(account.getJid().asBareJid().toString());
+ viewHolder.binding.accountJid.setText(account.getJid().asBareJid().toString());
}
- TextView statusView = view.findViewById(R.id.account_status);
- ImageView imageView = view.findViewById(R.id.account_image);
- loadAvatar(account,imageView);
- statusView.setText(getContext().getString(account.getStatus().getReadableId()));
+ loadAvatar(account, viewHolder.binding.accountImage);
+ viewHolder.binding.accountStatus.setText(getContext().getString(account.getStatus().getReadableId()));
switch (account.getStatus()) {
case ONLINE:
- statusView.setTextColor(StyledAttributes.getColor(activity, R.attr.TextColorOnline));
+ viewHolder.binding.accountStatus.setTextColor(StyledAttributes.getColor(activity, R.attr.TextColorOnline));
break;
case DISABLED:
case CONNECTING:
- statusView.setTextColor(StyledAttributes.getColor(activity, android.R.attr.textColorSecondary));
+ viewHolder.binding.accountStatus.setTextColor(StyledAttributes.getColor(activity, android.R.attr.textColorSecondary));
break;
default:
- statusView.setTextColor(StyledAttributes.getColor(activity, R.attr.TextColorError));
+ viewHolder.binding.accountStatus.setTextColor(StyledAttributes.getColor(activity, R.attr.TextColorError));
break;
}
- final SwitchCompat tglAccountState = view.findViewById(R.id.tgl_account_status);
final boolean isDisabled = (account.getStatus() == Account.State.DISABLED);
- tglAccountState.setOnCheckedChangeListener(null);
- tglAccountState.setChecked(!isDisabled);
+ viewHolder.binding.tglAccountStatus.setOnCheckedChangeListener(null);
+ viewHolder.binding.tglAccountStatus.setChecked(!isDisabled);
if (this.showStateButton) {
- tglAccountState.setVisibility(View.VISIBLE);
+ viewHolder.binding.tglAccountStatus.setVisibility(View.VISIBLE);
} else {
- tglAccountState.setVisibility(View.GONE);
+ viewHolder.binding.tglAccountStatus.setVisibility(View.GONE);
}
- tglAccountState.setOnCheckedChangeListener((compoundButton, b) -> {
+ viewHolder.binding.tglAccountStatus.setOnCheckedChangeListener((compoundButton, b) -> {
if (b == isDisabled && activity instanceof OnTglAccountState) {
((OnTglAccountState) activity).onClickTglAccountState(account, b);
}
@@ -92,6 +89,62 @@ public class AccountAdapter extends ArrayAdapter<Account> {
return view;
}
+ private static class ViewHolder {
+ private final AccountRowBinding binding;
+
+ private ViewHolder(AccountRowBinding binding) {
+ this.binding = binding;
+ }
+ }
+
+ class BitmapWorkerTask extends AsyncTask<Account, Void, Bitmap> {
+ private final WeakReference<ImageView> imageViewReference;
+ private Account account = null;
+
+ public BitmapWorkerTask(ImageView imageView) {
+ imageViewReference = new WeakReference<>(imageView);
+ }
+
+ @Override
+ protected Bitmap doInBackground(Account... params) {
+ this.account = params[0];
+ return activity.avatarService().get(this.account, activity.getPixel(48), isCancelled());
+ }
+
+ @Override
+ protected void onPostExecute(Bitmap bitmap) {
+ if (bitmap != null && !isCancelled()) {
+ final ImageView imageView = imageViewReference.get();
+ if (imageView != null) {
+ imageView.setImageBitmap(bitmap);
+ imageView.setBackgroundColor(0x00000000);
+ }
+ }
+ }
+ }
+
+ public void loadAvatar(Account account, ImageView imageView) {
+ if (cancelPotentialWork(account, imageView)) {
+ final Bitmap bm = activity.avatarService().get(account, activity.getPixel(48), true);
+ if (bm != null) {
+ cancelPotentialWork(account, imageView);
+ imageView.setImageBitmap(bm);
+ imageView.setBackgroundColor(0x00000000);
+ } else {
+ imageView.setBackgroundColor(UIHelper.getColorForName(account.getJid().asBareJid().toString()));
+ imageView.setImageDrawable(null);
+ final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
+ final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
+ imageView.setImageDrawable(asyncDrawable);
+ try {
+ task.execute(account);
+ } catch (final RejectedExecutionException ignored) {
+ }
+ }
+ }
+ }
+
+
public interface OnTglAccountState {
void onClickTglAccountState(Account account, boolean state);
}
@@ -121,27 +174,6 @@ public class AccountAdapter extends ArrayAdapter<Account> {
return null;
}
- public void loadAvatar(Account account, ImageView imageView) {
- if (cancelPotentialWork(account, imageView)) {
- final Bitmap bm = activity.avatarService().get(account, activity.getPixel(56), true);
- if (bm != null) {
- cancelPotentialWork(account, imageView);
- imageView.setImageBitmap(bm);
- imageView.setBackgroundColor(0x00000000);
- } else {
- imageView.setBackgroundColor(UIHelper.getColorForName(account.getJid().asBareJid().toString()));
- imageView.setImageDrawable(null);
- final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
- final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
- imageView.setImageDrawable(asyncDrawable);
- try {
- task.executeOnExecutor(BitmapWorkerTask.THREAD_POOL_EXECUTOR, account);
- } catch (final RejectedExecutionException ignored) {
- }
- }
- }
- }
-
static class AsyncDrawable extends BitmapDrawable {
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
@@ -154,30 +186,4 @@ public class AccountAdapter extends ArrayAdapter<Account> {
return bitmapWorkerTaskReference.get();
}
}
-
- class BitmapWorkerTask extends AsyncTask<Account, Void, Bitmap> {
- private final WeakReference<ImageView> imageViewReference;
- private Account account = null;
-
- public BitmapWorkerTask(ImageView imageView) {
- imageViewReference = new WeakReference<>(imageView);
- }
-
- @Override
- protected Bitmap doInBackground(Account... params) {
- this.account = params[0];
- return activity.avatarService().get(this.account, activity.getPixel(56), isCancelled());
- }
-
- @Override
- protected void onPostExecute(Bitmap bitmap) {
- if (bitmap != null && !isCancelled()) {
- final ImageView imageView = imageViewReference.get();
- if (imageView != null) {
- imageView.setImageBitmap(bitmap);
- imageView.setBackgroundColor(0x00000000);
- }
- }
- }
- }
}
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/BackupFileAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/BackupFileAdapter.java
new file mode 100644
index 000000000..84ae61e11
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/ui/adapter/BackupFileAdapter.java
@@ -0,0 +1,167 @@
+package de.pixart.messenger.ui.adapter;
+
+import android.content.res.Resources;
+import android.databinding.DataBindingUtil;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.support.annotation.NonNull;
+import android.support.v7.widget.RecyclerView;
+import android.text.format.DateUtils;
+import android.util.DisplayMetrics;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.RejectedExecutionException;
+
+import de.pixart.messenger.R;
+import de.pixart.messenger.databinding.AccountRowBinding;
+import de.pixart.messenger.services.AvatarService;
+import de.pixart.messenger.services.ImportBackupService;
+import de.pixart.messenger.utils.BackupFileHeader;
+import de.pixart.messenger.utils.UIHelper;
+import rocks.xmpp.addr.Jid;
+
+public class BackupFileAdapter extends RecyclerView.Adapter<BackupFileAdapter.BackupFileViewHolder> {
+
+ private OnItemClickedListener listener;
+
+ private final List<ImportBackupService.BackupFile> files = new ArrayList<>();
+
+
+ @NonNull
+ @Override
+ public BackupFileViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
+ return new BackupFileViewHolder(DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), R.layout.account_row, viewGroup, false));
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull BackupFileViewHolder backupFileViewHolder, int position) {
+ final ImportBackupService.BackupFile backupFile = files.get(position);
+ final BackupFileHeader header = backupFile.getHeader();
+ backupFileViewHolder.binding.accountJid.setText(header.getJid().asBareJid().toString());
+ backupFileViewHolder.binding.accountStatus.setText(String.format("%s ยท %s", header.getApp(), DateUtils.formatDateTime(backupFileViewHolder.binding.getRoot().getContext(), header.getTimestamp(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR)));
+ backupFileViewHolder.binding.tglAccountStatus.setVisibility(View.GONE);
+ backupFileViewHolder.binding.getRoot().setOnClickListener(v -> {
+ if (listener != null) {
+ listener.onClick(backupFile);
+ }
+ });
+ loadAvatar(header.getJid(), backupFileViewHolder.binding.accountImage);
+ }
+
+ @Override
+ public int getItemCount() {
+ return files.size();
+ }
+
+ public void setFiles(List<ImportBackupService.BackupFile> files) {
+ this.files.clear();
+ this.files.addAll(files);
+ notifyDataSetChanged();
+ }
+
+ public void setOnItemClickedListener(OnItemClickedListener listener) {
+ this.listener = listener;
+ }
+
+ static class BackupFileViewHolder extends RecyclerView.ViewHolder {
+ private final AccountRowBinding binding;
+
+ BackupFileViewHolder(AccountRowBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ }
+ }
+
+ public interface OnItemClickedListener {
+ void onClick(ImportBackupService.BackupFile backupFile);
+ }
+
+ static class BitmapWorkerTask extends AsyncTask<Jid, Void, Bitmap> {
+ private final WeakReference<ImageView> imageViewReference;
+ private Jid jid = null;
+ private final int size;
+
+ BitmapWorkerTask(ImageView imageView) {
+ imageViewReference = new WeakReference<>(imageView);
+ DisplayMetrics metrics = imageView.getContext().getResources().getDisplayMetrics();
+ this.size = ((int) (48 * metrics.density));
+ }
+
+ @Override
+ protected Bitmap doInBackground(Jid... params) {
+ this.jid = params[0];
+ return AvatarService.get(this.jid, size);
+ }
+
+ @Override
+ protected void onPostExecute(Bitmap bitmap) {
+ if (bitmap != null && !isCancelled()) {
+ final ImageView imageView = imageViewReference.get();
+ if (imageView != null) {
+ imageView.setImageBitmap(bitmap);
+ imageView.setBackgroundColor(0x00000000);
+ }
+ }
+ }
+ }
+
+ private void loadAvatar(Jid jid, ImageView imageView) {
+ if (cancelPotentialWork(jid, imageView)) {
+ imageView.setBackgroundColor(UIHelper.getColorForName(jid.asBareJid().toString()));
+ imageView.setImageDrawable(null);
+ final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
+ final AsyncDrawable asyncDrawable = new AsyncDrawable(imageView.getContext().getResources(), null, task);
+ imageView.setImageDrawable(asyncDrawable);
+ try {
+ task.execute(jid);
+ } catch (final RejectedExecutionException ignored) {
+ }
+ }
+ }
+
+ private static boolean cancelPotentialWork(Jid jid, ImageView imageView) {
+ final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
+
+ if (bitmapWorkerTask != null) {
+ final Jid oldJid = bitmapWorkerTask.jid;
+ if (oldJid == null || jid != oldJid) {
+ bitmapWorkerTask.cancel(true);
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
+ if (imageView != null) {
+ final Drawable drawable = imageView.getDrawable();
+ if (drawable instanceof AsyncDrawable) {
+ final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+ return asyncDrawable.getBitmapWorkerTask();
+ }
+ }
+ return null;
+ }
+
+ static class AsyncDrawable extends BitmapDrawable {
+ private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
+
+ AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
+ super(res, bitmap);
+ bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
+ }
+
+ BitmapWorkerTask getBitmapWorkerTask() {
+ return bitmapWorkerTaskReference.get();
+ }
+ }
+} \ No newline at end of file