diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 07863ffc6..ec2303564 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -30,6 +30,7 @@
+
diff --git a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java
index c40c6d051..3e9555ca3 100644
--- a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java
+++ b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java
@@ -2,6 +2,7 @@ package eu.siacs.conversations.generator;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
+import eu.siacs.conversations.entities.Presences;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
@@ -36,8 +37,22 @@ public class PresenceGenerator extends AbstractGenerator {
return subscription("subscribed", contact);
}
- public PresencePacket sendPresence(Account account) {
+ public PresencePacket selfPresence(Account account, int presence) {
PresencePacket packet = new PresencePacket();
+ switch(presence) {
+ case Presences.AWAY:
+ packet.addChild("show").setContent("away");
+ break;
+ case Presences.XA:
+ packet.addChild("show").setContent("xa");
+ break;
+ case Presences.CHAT:
+ packet.addChild("show").setContent("chat");
+ break;
+ case Presences.DND:
+ packet.addChild("show").setContent("dnd");
+ break;
+ }
packet.setFrom(account.getJid());
String sig = account.getPgpSignature();
if (sig != null) {
diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java
index 4fd7fde7c..3ed155a82 100644
--- a/src/main/java/eu/siacs/conversations/services/NotificationService.java
+++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java
@@ -115,29 +115,13 @@ public class NotificationService {
return mXmppConnectionService.getPreferences().getBoolean("always_notify_in_conference", false);
}
- @SuppressLint("NewApi")
- @SuppressWarnings("deprecation")
- private boolean isInteractive() {
- final PowerManager pm = (PowerManager) mXmppConnectionService
- .getSystemService(Context.POWER_SERVICE);
-
- final boolean isScreenOn;
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
- isScreenOn = pm.isScreenOn();
- } else {
- isScreenOn = pm.isInteractive();
- }
-
- return isScreenOn;
- }
-
public void push(final Message message) {
mXmppConnectionService.updateUnreadCountBadge();
if (!notify(message)) {
return;
}
- final boolean isScreenOn = isInteractive();
+ final boolean isScreenOn = mXmppConnectionService.isInteractive();
if (this.mIsInForeground && isScreenOn && this.mOpenConversation == message.getConversation()) {
return;
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index 8326766e5..18094cfbe 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -6,13 +6,16 @@ import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.graphics.Bitmap;
+import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.FileObserver;
import android.os.IBinder;
@@ -61,6 +64,7 @@ import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.MucOptions;
import eu.siacs.conversations.entities.MucOptions.OnRenameListener;
+import eu.siacs.conversations.entities.Presences;
import eu.siacs.conversations.entities.Transferable;
import eu.siacs.conversations.entities.TransferablePlaceholder;
import eu.siacs.conversations.generator.IqGenerator;
@@ -313,6 +317,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
private PowerManager pm;
private LruCache mBitmapCache;
private Thread mPhoneContactMergerThread;
+ private EventReceiver mEventReceiver = new EventReceiver();
private boolean mRestoredFromDatabase = false;
public boolean areMessagesInitialized() {
@@ -444,6 +449,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
final String action = intent == null ? null : intent.getAction();
boolean interactive = false;
if (action != null) {
+ Log.d(Config.LOGTAG,"action: "+action);
switch (action) {
case ConnectivityManager.CONNECTIVITY_ACTION:
if (hasInternetConnection() && Config.RESET_ATTEMPT_COUNT_ON_NETWORK_CHANGE) {
@@ -483,6 +489,17 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
break;
}
break;
+ case AudioManager.RINGER_MODE_CHANGED_ACTION:
+ if (xaOnSilentMode()) {
+ refreshAllPresences();
+ }
+ break;
+ case Intent.ACTION_SCREEN_OFF:
+ case Intent.ACTION_SCREEN_ON:
+ if (awayWhenScreenOff()) {
+ refreshAllPresences();
+ }
+ break;
}
}
this.wakeLock.acquire();
@@ -544,10 +561,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
}
}
- /*PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
- if (!pm.isScreenOn()) {
- removeStaleListeners();
- }*/
if (wakeLock.isHeld()) {
try {
wakeLock.release();
@@ -557,6 +570,43 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
return START_STICKY;
}
+ private boolean xaOnSilentMode() {
+ return getPreferences().getBoolean("xa_on_silent_mode", false);
+ }
+
+ private boolean awayWhenScreenOff() {
+ return getPreferences().getBoolean("away_when_screen_off", false);
+ }
+
+ private int getTargetPresence() {
+ if (xaOnSilentMode() && isPhoneSilenced()) {
+ return Presences.XA;
+ } else if (awayWhenScreenOff() && !isInteractive()) {
+ return Presences.AWAY;
+ } else {
+ return Presences.ONLINE;
+ }
+ }
+
+ @SuppressLint("NewApi")
+ @SuppressWarnings("deprecation")
+ public boolean isInteractive() {
+ final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+
+ final boolean isScreenOn;
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+ isScreenOn = pm.isScreenOn();
+ } else {
+ isScreenOn = pm.isInteractive();
+ }
+ return isScreenOn;
+ }
+
+ private boolean isPhoneSilenced() {
+ AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+ return audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT;
+ }
+
private void resetAllAttemptCounts(boolean reallyAll) {
Log.d(Config.LOGTAG,"resetting all attepmt counts");
for(Account account : accounts) {
@@ -599,6 +649,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contactObserver);
this.fileObserver.startWatching();
+
this.pgpServiceConnection = new OpenPgpServiceConnection(getApplicationContext(), "org.sufficientlysecure.keychain");
this.pgpServiceConnection.bindToService();
@@ -606,6 +657,23 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"XmppConnectionService");
toggleForegroundService();
updateUnreadCountBadge();
+ toggleScreenEventReceiver();
+ }
+
+ @Override
+ public void onDestroy() {
+ unregisterReceiver(this.mEventReceiver);
+ super.onDestroy();
+ }
+
+ public void toggleScreenEventReceiver() {
+ if (awayWhenScreenOff()) {
+ final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ registerReceiver(this.mEventReceiver, filter);
+ } else {
+ unregisterReceiver(this.mEventReceiver);
+ }
}
public void toggleForegroundService() {
@@ -2502,7 +2570,15 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
public void sendPresence(final Account account) {
- sendPresencePacket(account, mPresenceGenerator.sendPresence(account));
+ sendPresencePacket(account, mPresenceGenerator.selfPresence(account, getTargetPresence()));
+ }
+
+ public void refreshAllPresences() {
+ for (Account account : getAccounts()) {
+ if (!account.isOptionSet(Account.OPTION_DISABLED)) {
+ sendPresence(account);
+ }
+ }
}
public void sendOfflinePresence(final Account account) {
diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java
index 6e5fe610b..eca7c0c14 100644
--- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java
@@ -148,13 +148,14 @@ public class SettingsActivity extends XmppActivity implements
}
} else if (name.equals("keep_foreground_service")) {
xmppConnectionService.toggleForegroundService();
- } else if (name.equals("confirm_messages")) {
+ } else if (name.equals("confirm_messages")
+ || name.equals("xa_on_silent_mode")
+ || name.equals("away_when_screen_off")) {
if (xmppConnectionServiceBound) {
- for (Account account : xmppConnectionService.getAccounts()) {
- if (!account.isOptionSet(Account.OPTION_DISABLED)) {
- xmppConnectionService.sendPresence(account);
- }
+ if (name.equals("away_when_screen_off")) {
+ xmppConnectionService.toggleScreenEventReceiver();
}
+ xmppConnectionService.refreshAllPresences();
}
} else if (name.equals("dont_trust_system_cas")) {
xmppConnectionService.updateMemorizingTrustmanager();
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 22e810eaa..29b531554 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -519,4 +519,9 @@
Show received messages as black text on a white background
Timeout in DNS
Broken
+ Presence settings
+ Away when screen is off
+ Marks your resource as away when the screen is turned off
+ Not available in silent mode
+ Marks your resource as not available when phone is in silent mode
diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml
index c78e9ede8..f05738ac5 100644
--- a/src/main/res/xml/preferences.xml
+++ b/src/main/res/xml/preferences.xml
@@ -159,6 +159,18 @@
android:summary="@string/pref_display_enter_key_summary"
android:title="@string/pref_display_enter_key"/>
+
+
+
+