introduced expert options to set status to away and xa if screen is off or if phone is silenced

Daniel Gultsch created

Change summary

src/main/AndroidManifest.xml                                             |  1 
src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java    | 17 
src/main/java/eu/siacs/conversations/services/NotificationService.java   | 18 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 86 
src/main/java/eu/siacs/conversations/ui/SettingsActivity.java            | 11 
src/main/res/values/strings.xml                                          |  5 
src/main/res/xml/preferences.xml                                         | 12 
7 files changed, 122 insertions(+), 28 deletions(-)

Detailed changes

src/main/AndroidManifest.xml 🔗

@@ -30,6 +30,7 @@
                 <action android:name="android.intent.action.BOOT_COMPLETED" />
                 <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                 <action android:name="android.intent.action.ACTION_SHUTDOWN" />
+                <action android:name="android.media.RINGER_MODE_CHANGED" />
             </intent-filter>
         </receiver>
 

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) {

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;

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<String, Bitmap> 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) {

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();

src/main/res/values/strings.xml 🔗

@@ -519,4 +519,9 @@
 	<string name="pref_use_white_background_summary">Show received messages as black text on a white background</string>
 	<string name="account_status_dns_timeout">Timeout in DNS</string>
 	<string name="server_info_broken">Broken</string>
+	<string name="pref_presence_settings">Presence settings</string>
+	<string name="pref_away_when_screen_off">Away when screen is off</string>
+	<string name="pref_away_when_screen_off_summary">Marks your resource as away when the screen is turned off</string>
+	<string name="pref_xa_on_silent_mode">Not available in silent mode</string>
+	<string name="pref_xa_on_silent_mode_summary">Marks your resource as not available when phone is in silent mode</string>
 </resources>

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"/>
             </PreferenceCategory>
+            <PreferenceCategory android:title="@string/pref_presence_settings">
+                <CheckBoxPreference
+                    android:defaultValue="false"
+                    android:key="away_when_screen_off"
+                    android:summary="@string/pref_away_when_screen_off_summary"
+                    android:title="@string/pref_away_when_screen_off"/>
+                <CheckBoxPreference
+                    android:defaultValue="false"
+                    android:key="xa_on_silent_mode"
+                    android:summary="@string/pref_xa_on_silent_mode_summary"
+                    android:title="@string/pref_xa_on_silent_mode"/>
+            </PreferenceCategory>
             <PreferenceCategory android:title="@string/pref_expert_options_other">
                 <CheckBoxPreference
                     android:defaultValue="false"