aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/pixart/messenger/services
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/pixart/messenger/services')
-rw-r--r--src/main/java/de/pixart/messenger/services/AbstractConnectionManager.java120
-rw-r--r--src/main/java/de/pixart/messenger/services/ContactChooserTargetService.java6
-rw-r--r--src/main/java/de/pixart/messenger/services/ExportLogsService.java4
-rw-r--r--src/main/java/de/pixart/messenger/services/XmppConnectionService.java37
4 files changed, 85 insertions, 82 deletions
diff --git a/src/main/java/de/pixart/messenger/services/AbstractConnectionManager.java b/src/main/java/de/pixart/messenger/services/AbstractConnectionManager.java
index 1c4c6ca19..65711ef42 100644
--- a/src/main/java/de/pixart/messenger/services/AbstractConnectionManager.java
+++ b/src/main/java/de/pixart/messenger/services/AbstractConnectionManager.java
@@ -1,85 +1,39 @@
package de.pixart.messenger.services;
-import android.Manifest;
import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Build;
import android.os.PowerManager;
import android.os.SystemClock;
-import android.util.Log;
import android.util.Pair;
-import org.bouncycastle.crypto.engines.AESEngine;
-import org.bouncycastle.crypto.modes.AEADBlockCipher;
-import org.bouncycastle.crypto.modes.GCMBlockCipher;
-import org.bouncycastle.crypto.params.AEADParameters;
-import org.bouncycastle.crypto.params.KeyParameter;
-
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
import java.util.concurrent.atomic.AtomicLong;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
-import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
-import de.pixart.messenger.Config;
import de.pixart.messenger.R;
import de.pixart.messenger.entities.DownloadableFile;
+import de.pixart.messenger.utils.Compatibility;
public class AbstractConnectionManager {
- protected XmppConnectionService mXmppConnectionService;
+ private static final String KEYTYPE = "AES";
+ private static final String CIPHERMODE = "AES/GCM/NoPadding";
+ private static final String PROVIDER = "BC";
private static final int UI_REFRESH_THRESHOLD = 250;
private static final AtomicLong LAST_UI_UPDATE_CALL = new AtomicLong(0);
+ protected XmppConnectionService mXmppConnectionService;
public AbstractConnectionManager(XmppConnectionService service) {
this.mXmppConnectionService = service;
}
- public XmppConnectionService getXmppConnectionService() {
- return this.mXmppConnectionService;
- }
-
- public long getAutoAcceptFileSize() {
- long defaultValue_wifi = this.getXmppConnectionService().getResources().getInteger(R.integer.auto_accept_filesize_wifi);
- long defaultValue_mobile = this.getXmppConnectionService().getResources().getInteger(R.integer.auto_accept_filesize_mobile);
- long defaultValue_roaming = this.getXmppConnectionService().getResources().getInteger(R.integer.auto_accept_filesize_roaming);
-
- String config = "0";
- if (mXmppConnectionService.isWIFI()) {
- config = this.mXmppConnectionService.getPreferences().getString(
- "auto_accept_file_size_wifi", String.valueOf(defaultValue_wifi));
- } else if (mXmppConnectionService.isMobile()) {
- config = this.mXmppConnectionService.getPreferences().getString(
- "auto_accept_file_size_mobile", String.valueOf(defaultValue_mobile));
- } else if (mXmppConnectionService.isMobileRoaming()) {
- config = this.mXmppConnectionService.getPreferences().getString(
- "auto_accept_file_size_roaming", String.valueOf(defaultValue_roaming));
- }
- try {
- return Long.parseLong(config);
- } catch (NumberFormatException e) {
- return defaultValue_mobile;
- }
- }
-
- public boolean hasStoragePermission() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- return mXmppConnectionService.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
- } else {
- return true;
- }
- }
-
public static Pair<InputStream, Integer> createInputStream(DownloadableFile file, boolean gcm) throws FileNotFoundException {
FileInputStream is;
int size;
@@ -90,15 +44,15 @@ public class AbstractConnectionManager {
}
try {
if (gcm) {
- AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
- cipher.init(true, new AEADParameters(new KeyParameter(file.getKey()), 128, file.getIv()));
- InputStream cis = new org.bouncycastle.crypto.io.CipherInputStream(is, cipher);
- return new Pair<>(cis, cipher.getOutputSize(size));
+ Cipher cipher = Compatibility.twentyTwo() ? Cipher.getInstance(CIPHERMODE) : Cipher.getInstance(CIPHERMODE, PROVIDER);
+ SecretKeySpec keySpec = new SecretKeySpec(file.getKey(), KEYTYPE);
+ IvParameterSpec ivSpec = new IvParameterSpec(file.getIv());
+ cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
+ return new Pair<>(new CipherInputStream(is, cipher), cipher.getOutputSize(size));
} else {
IvParameterSpec ips = new IvParameterSpec(file.getIv());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(file.getKey(), "AES"), ips);
- Log.d(Config.LOGTAG, "opening encrypted input stream");
+ cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(file.getKey(), KEYTYPE), ips);
return new Pair<>(new CipherInputStream(is, cipher), (size / 16 + 1) * 16);
}
} catch (Exception e) {
@@ -126,27 +80,53 @@ public class AbstractConnectionManager {
}
try {
if (gcm) {
- AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
- cipher.init(false, new AEADParameters(new KeyParameter(file.getKey()), 128, file.getIv()));
- return new org.bouncycastle.crypto.io.CipherOutputStream(os, cipher);
+ Cipher cipher = Compatibility.twentyTwo() ? Cipher.getInstance(CIPHERMODE) : Cipher.getInstance(CIPHERMODE, PROVIDER);
+ SecretKeySpec keySpec = new SecretKeySpec(file.getKey(), KEYTYPE);
+ IvParameterSpec ivSpec = new IvParameterSpec(file.getIv());
+ cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
+ return new CipherOutputStream(os, cipher);
} else {
IvParameterSpec ips = new IvParameterSpec(file.getIv());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(file.getKey(), "AES"), ips);
- Log.d(Config.LOGTAG, "opening encrypted output stream");
+ cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(file.getKey(), KEYTYPE), ips);
return new CipherOutputStream(os, cipher);
}
- } catch (InvalidKeyException e) {
- return null;
- } catch (NoSuchAlgorithmException e) {
- return null;
- } catch (NoSuchPaddingException e) {
- return null;
- } catch (InvalidAlgorithmParameterException e) {
- return null;
+ } catch (Exception e) {
+ throw new AssertionError(e);
}
}
+ public XmppConnectionService getXmppConnectionService() {
+ return this.mXmppConnectionService;
+ }
+
+ public long getAutoAcceptFileSize() {
+ long defaultValue_wifi = this.getXmppConnectionService().getResources().getInteger(R.integer.auto_accept_filesize_wifi);
+ long defaultValue_mobile = this.getXmppConnectionService().getResources().getInteger(R.integer.auto_accept_filesize_mobile);
+ long defaultValue_roaming = this.getXmppConnectionService().getResources().getInteger(R.integer.auto_accept_filesize_roaming);
+
+ String config = "0";
+ if (mXmppConnectionService.isWIFI()) {
+ config = this.mXmppConnectionService.getPreferences().getString(
+ "auto_accept_file_size_wifi", String.valueOf(defaultValue_wifi));
+ } else if (mXmppConnectionService.isMobile()) {
+ config = this.mXmppConnectionService.getPreferences().getString(
+ "auto_accept_file_size_mobile", String.valueOf(defaultValue_mobile));
+ } else if (mXmppConnectionService.isMobileRoaming()) {
+ config = this.mXmppConnectionService.getPreferences().getString(
+ "auto_accept_file_size_roaming", String.valueOf(defaultValue_roaming));
+ }
+ try {
+ return Long.parseLong(config);
+ } catch (NumberFormatException e) {
+ return defaultValue_mobile;
+ }
+ }
+
+ public boolean hasStoragePermission() {
+ return Compatibility.hasStoragePermission(mXmppConnectionService);
+ }
+
public void updateConversationUi(boolean force) {
synchronized (LAST_UI_UPDATE_CALL) {
if (force || SystemClock.elapsedRealtime() - LAST_UI_UPDATE_CALL.get() >= UI_REFRESH_THRESHOLD) {
diff --git a/src/main/java/de/pixart/messenger/services/ContactChooserTargetService.java b/src/main/java/de/pixart/messenger/services/ContactChooserTargetService.java
index d20f9c1f3..4c0aec3ca 100644
--- a/src/main/java/de/pixart/messenger/services/ContactChooserTargetService.java
+++ b/src/main/java/de/pixart/messenger/services/ContactChooserTargetService.java
@@ -17,7 +17,7 @@ import java.util.ArrayList;
import java.util.List;
import de.pixart.messenger.entities.Conversation;
-import de.pixart.messenger.ui.ShareWithActivity;
+import de.pixart.messenger.ui.ConversationsActivity;
@TargetApi(Build.VERSION_CODES.M)
public class ContactChooserTargetService extends ChooserTargetService implements ServiceConnection {
@@ -41,7 +41,7 @@ public class ContactChooserTargetService extends ChooserTargetService implements
return chooserTargets;
}
mXmppConnectionService.populateWithOrderedConversations(conversations, false);
- final ComponentName componentName = new ComponentName(this, ShareWithActivity.class);
+ final ComponentName componentName = new ComponentName(this, ConversationsActivity.class);
final int pixel = (int) (48 * getResources().getDisplayMetrics().density);
for (Conversation conversation : conversations) {
if (conversation.sentMessagesCount() == 0) {
@@ -51,7 +51,7 @@ public class ContactChooserTargetService extends ChooserTargetService implements
final Icon icon = Icon.createWithBitmap(mXmppConnectionService.getAvatarService().get(conversation, pixel));
final float score = 1 - (1.0f / MAX_TARGETS) * chooserTargets.size();
final Bundle extras = new Bundle();
- extras.putString("uuid", conversation.getUuid());
+ extras.putString(ConversationsActivity.EXTRA_CONVERSATION, conversation.getUuid());
chooserTargets.add(new ChooserTarget(name, icon, score, componentName, extras));
if (chooserTargets.size() >= MAX_TARGETS) {
break;
diff --git a/src/main/java/de/pixart/messenger/services/ExportLogsService.java b/src/main/java/de/pixart/messenger/services/ExportLogsService.java
index b0da108ba..e66873acc 100644
--- a/src/main/java/de/pixart/messenger/services/ExportLogsService.java
+++ b/src/main/java/de/pixart/messenger/services/ExportLogsService.java
@@ -41,7 +41,7 @@ import static de.pixart.messenger.ui.SettingsActivity.USE_MULTI_ACCOUNTS;
public class ExportLogsService extends XmppConnectionService {
private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
- private static final String DIRECTORY_STRING_FORMAT = FileBackend.getConversationsDirectory("Chats", false) + "%s";
+ private static final String DIRECTORY_STRING_FORMAT = FileBackend.getAppLogsDirectory() + "%s";
private static final String MESSAGE_STRING_FORMAT = "(%s) %s: %s\n";
private static AtomicBoolean running = new AtomicBoolean(false);
boolean ReadableLogsEnabled = false;
@@ -171,7 +171,7 @@ public class ExportLogsService extends XmppConnectionService {
// Get hold of the db:
FileInputStream InputFile = new FileInputStream(this.getDatabasePath(DatabaseBackend.DATABASE_NAME));
// Set the output folder on the SDcard
- File directory = new File(FileBackend.getConversationsDirectory("Database", false));
+ File directory = new File(FileBackend.getBackupDirectory());
// Create the folder if it doesn't exist:
if (!directory.exists()) {
boolean directory_created = directory.mkdirs();
diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
index b6d23668c..525354957 100644
--- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
+++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
@@ -116,6 +116,7 @@ import de.pixart.messenger.persistance.FileBackend;
import de.pixart.messenger.ui.SettingsActivity;
import de.pixart.messenger.ui.UiCallback;
import de.pixart.messenger.ui.interfaces.OnAvatarPublication;
+import de.pixart.messenger.ui.interfaces.OnMediaLoaded;
import de.pixart.messenger.ui.interfaces.OnSearchResultsAvailable;
import de.pixart.messenger.utils.Compatibility;
import de.pixart.messenger.utils.ConversationsFileObserver;
@@ -431,7 +432,6 @@ public class XmppConnectionService extends Service {
public void stopForcingForegroundNotification() {
mForceForegroundService.set(false);
toggleForegroundService();
- mNotificationService.dismissForcedForegroundNotification();
}
public boolean areMessagesInitialized() {
@@ -727,6 +727,7 @@ public class XmppConnectionService extends Service {
}
private boolean processAccountState(Account account, boolean interactive, boolean isUiAction, boolean isAccountPushed, HashSet<Account> pingCandidates) {
+ storeNumberOfAccounts(this.getAccounts().size());
boolean pingNow = false;
if (account.getStatus().isAttemptReconnect()) {
if (!hasInternetConnection()) {
@@ -802,6 +803,14 @@ public class XmppConnectionService extends Service {
return pingNow;
}
+ private void storeNumberOfAccounts(int accounts) {
+ //write No of accounts to file
+ final SharedPreferences.Editor editor = getPreferences().edit();
+ Log.d(Config.LOGTAG, "Number of accounts is " + accounts);
+ editor.putInt(SettingsActivity.NUMBER_OF_ACCOUNTS, accounts);
+ editor.apply();
+ }
+
public boolean isDataSaverDisabled() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
@@ -1126,7 +1135,7 @@ public class XmppConnectionService extends Service {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
startContactObserver();
}
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
+ if (Compatibility.hasStoragePermission(this)) {
Log.d(Config.LOGTAG, "starting file observer");
new Thread(fileObserver::startWatching).start();
}
@@ -1224,19 +1233,21 @@ public class XmppConnectionService extends Service {
}
public void toggleForegroundService() {
- if (mForceForegroundService.get() || (Compatibility.keepForegroundService(this) && hasEnabledAccounts())) {
+ final boolean status;
+ if (mForceForegroundService.get() || (Compatibility.keepForegroundService(this)/* && hasEnabledAccounts()*/)) {
startForeground(NotificationService.FOREGROUND_NOTIFICATION_ID, this.mNotificationService.createForegroundNotification());
- Log.d(Config.LOGTAG, "started foreground service");
+ status = true;
} else {
stopForeground(true);
- Log.d(Config.LOGTAG, "stopped foreground service");
+ status = false;
}
+ mNotificationService.dismissForcedForegroundNotification(); //if the channel was changed the previous call might fail
+ Log.d(Config.LOGTAG, "ForegroundService: " + (status ? "on" : "off"));
}
@Override
public void onTaskRemoved(final Intent rootIntent) {
super.onTaskRemoved(rootIntent);
- //TODO check for accounts enabled
if ((Compatibility.keepForegroundService(this) && hasEnabledAccounts()) || mForceForegroundService.get()) {
Log.d(Config.LOGTAG, "ignoring onTaskRemoved because foreground service is activated");
} else {
@@ -2661,7 +2672,7 @@ public class XmppConnectionService extends Service {
private boolean hasEnabledAccounts() {
if (this.accounts == null) {
- return true; // set to true if accounts could not be fetched - used for notifications
+ return false; // set to false if accounts could not be fetched - used for notifications
}
for (Account account : this.accounts) {
if (account.isEnabled()) {
@@ -2671,6 +2682,18 @@ public class XmppConnectionService extends Service {
return false;
}
+ public void getAttachments(final Conversation conversation, int limit, final OnMediaLoaded onMediaLoaded) {
+ getAttachments(conversation.getAccount(), conversation.getJid().asBareJid(), limit, onMediaLoaded);
+ }
+
+ public void getAttachments(final Account account, final Jid jid, final int limit, final OnMediaLoaded onMediaLoaded) {
+ getAttachments(account.getUuid(), jid.asBareJid(), limit, onMediaLoaded);
+ }
+
+ public void getAttachments(final String account, final Jid jid, final int limit, final OnMediaLoaded onMediaLoaded) {
+ new Thread(() -> onMediaLoaded.onMediaLoaded(fileBackend.convertToAttachments(databaseBackend.getRelativeFilePaths(account, jid, limit)))).start();
+ }
+
public void persistSelfNick(MucOptions.User self) {
final Conversation conversation = self.getConversation();
Jid full = self.getFullJid();