pull/1706/head
alansley 4 months ago
parent af602df969
commit c4644e52bd

@ -169,7 +169,7 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
@Inject LokiAPIDatabase apiDB;
@Inject EmojiSearchDatabase emojiSearchDb;
private volatile boolean isAppVisible;
public static volatile boolean isAppVisible;
@Override
public Object getSystemService(String name) {

@ -32,6 +32,7 @@ import org.session.libsession.messaging.utilities.UpdateMessageData;
import org.session.libsession.utilities.IdentityKeyMismatch;
import org.session.libsession.utilities.NetworkFailure;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
import java.util.List;
@ -145,8 +146,11 @@ public abstract class MessageRecord extends DisplayRecord {
} else if (isOutgoingCall()) {
callType = CallMessageType.CALL_OUTGOING;
} else if (isMissedCall()) {
Log.w("ACL", "We think CALL_MISSSED");
callType = CallMessageType.CALL_MISSED;
} else {
Log.w("ACL", "We think CALL_FIRST_MISSSED");
callType = CallMessageType.CALL_FIRST_MISSED;
}
return new SpannableString(UpdateMessageBuilder.INSTANCE.buildCallMessage(context, callType, getIndividualRecipient().getAddress().serialize()));

@ -105,7 +105,7 @@ public class ThreadRecord extends DisplayRecord {
@Override
public CharSequence getDisplayBody(@NonNull Context context) {
// no need to display anything if there are no messages
if(lastMessage == null){
if (lastMessage == null){
return "";
}
else if (isGroupUpdateMessage()) {

@ -45,6 +45,7 @@ import org.session.libsession.messaging.utilities.SodiumUtilities.blindedKeyPair
import org.session.libsession.utilities.Address.Companion.fromSerialized
import org.session.libsession.utilities.ServiceUtil
import org.session.libsession.utilities.StringSubstitutionConstants.EMOJI_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.NAME_KEY
import org.session.libsession.utilities.TextSecurePreferences.Companion.getLocalNumber
import org.session.libsession.utilities.TextSecurePreferences.Companion.getNotificationPrivacy
import org.session.libsession.utilities.TextSecurePreferences.Companion.getRepeatAlertsCount
@ -280,12 +281,21 @@ class DefaultMessageNotifier : MessageNotifier {
builder.putStringExtra(LATEST_MESSAGE_ID_TAG, messageIdTag)
val text = notifications[0].text
val notificationText = notifications[0].text
// TODO: We get missed call notifications whenever we get a call - I have no idea why, and it would be better to strip them out
// TODO: at the source - but I'll stop them here if we recognise the notification text and the home screen is visible
// For some reason, even when we're starting a call we get a missed call notification - so we'll bail before that happens.
// TODO: Probably better to fix this at the source so that this never gets called rather then here - do this.
val missedCallString = Phrase.from(context, R.string.callsMissedCallFrom).put(NAME_KEY, notifications[0].recipient.name).format()
if (ApplicationContext.isAppVisible && notificationText == missedCallString) { return }
builder.setThread(notifications[0].recipient)
builder.setMessageCount(notificationState.messageCount)
val builderCS = text ?: ""
val builderCS = notificationText ?: ""
val ss = highlightMentions(
builderCS,
false,
@ -331,7 +341,6 @@ class DefaultMessageNotifier : MessageNotifier {
}
val iterator: ListIterator<NotificationItem> = notifications.listIterator(notifications.size)
while (iterator.hasPrevious()) {
val item = iterator.previous()
builder.addMessageBody(item.recipient, item.individualRecipient, item.text)
@ -363,6 +372,8 @@ class DefaultMessageNotifier : MessageNotifier {
// for ActivityCompat#requestPermissions for more details.
return
}
NotificationManagerCompat.from(context).notify(notificationId, notification)
Log.i(TAG, "Posted notification. $notification")
}

@ -235,6 +235,7 @@ public class KeyCachingService extends Service {
private void foregroundService() {
if (TextSecurePreferences.isPasswordDisabled(this) && !TextSecurePreferences.isScreenLockEnabled(this)) {
Log.w("ACL", "Stopping foreground service in KeyCachingService");
stopForeground(true);
return;
}
@ -248,8 +249,6 @@ public class KeyCachingService extends Service {
.put(APP_NAME_KEY, c.getString(R.string.app_name))
.format().toString();
builder.setContentTitle(unlockedTxt);
builder.setContentText(getString(R.string.lockAppUnlock));
builder.setSmallIcon(R.drawable.icon_cached);
builder.setWhen(0);
builder.setPriority(Notification.PRIORITY_MIN);

@ -334,7 +334,7 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
networkChangedReceiver = NetworkChangeReceiver(::networkChange)
networkChangedReceiver!!.register(this)
Log.w("ACL", "Lesssgo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
//Log.w("ACL", "Lesssgo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
//if (appIsBackground(this)) {
// ServiceCompat.startForeground(this,
// CallNotificationBuilder.WEBRTC_NOTIFICATION,
@ -342,18 +342,10 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
// if (Build.VERSION.SDK_INT >= 30) ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL else 0
// )
// Get the KeyguardManager and PowerManager
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
// Check if the phone is locked
val isPhoneLocked = keyguardManager.isKeyguardLocked
// Check if the screen is awake
val isScreenAwake = powerManager.isInteractive
// If the screen is off or phone is locked, wake it up
if (!isScreenAwake || isPhoneLocked) { wakeUpDevice() }
//if (!isScreenAwake || isPhoneLocked) { wakeUpDevice() }
// ServiceCompat.startForeground(
@ -365,23 +357,7 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
// )
}
private fun wakeUpDevice() {
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
val wakeLock = powerManager.newWakeLock(
PowerManager.FULL_WAKE_LOCK or
PowerManager.ACQUIRE_CAUSES_WAKEUP or
PowerManager.ON_AFTER_RELEASE,
"${NonTranslatableStringConstants.APP_NAME}:WakeLock"
)
// Acquire the wake lock to wake up the device
wakeLock.acquire(3000) // Wake up for 3 seconds
// Dismiss the keyguard
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val keyguardLock = keyguardManager.newKeyguardLock("MyApp:KeyguardLock")
keyguardLock.disableKeyguard()
}
private fun registerUncaughtExceptionHandler() {
uncaughtExceptionHandlerManager = UncaughtExceptionHandlerManager().apply {
@ -777,9 +753,51 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
}
}
private fun wakeUpDeviceIfLocked() {
// Get the KeyguardManager and PowerManager
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
// Check if the phone is locked
val isPhoneLocked = keyguardManager.isKeyguardLocked
// Check if the screen is awake
val isScreenAwake = powerManager.isInteractive
if (!isScreenAwake) {
Log.w("ACL", "Screen is NOT awake - waking it up!")
val wakeLock = powerManager.newWakeLock(
PowerManager.FULL_WAKE_LOCK or
PowerManager.ACQUIRE_CAUSES_WAKEUP or
PowerManager.ON_AFTER_RELEASE,
"${NonTranslatableStringConstants.APP_NAME}:WakeLock"
)
// Acquire the wake lock to wake up the device
wakeLock.acquire(3000) // Wake up for 3 seconds
val startTime = System.currentTimeMillis()
while (!powerManager.isInteractive) { /* Busy wait until we're awake */ }
val endTime = System.currentTimeMillis()
val duration = endTime - startTime
Log.w("ACL", "Woken up in $duration ms")
} else {
Log.w("ACL", "Screen is awake - doing nothing")
}
// Dismiss the keyguard
val keyguardLock = keyguardManager.newKeyguardLock("MyApp:KeyguardLock")
keyguardLock.disableKeyguard()
}
// Over the course of setting up a phonecall this method is called multiple times with `types` of PRE_OFFER -> RING_INCOMING -> ICE_MESSAGE
private fun setCallInProgressNotification(type: Int, recipient: Recipient?) {
wakeUpDeviceIfLocked()
val typeString = when (type) {
TYPE_INCOMING_RINGING -> "TYPE_INCOMING_RINGING"
TYPE_OUTGOING_RINGING -> "TYPE_OUTGOING_RINGING"
@ -789,7 +807,7 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
WEBRTC_NOTIFICATION -> "WEBRTC_NOTIFICATION"
else -> "We have no idea!"
}
Log.w("ACL", "Hit setCallInProgressNotification with type: $typeString")
Log.w("ACL", "NOOOOOOOOOOTIFICATION - Hit setCallInProgressNotification with type: $typeString")
// If notifications are enabled we'll try and start a foreground service to show the notification
var failedToStartForegroundService = false
@ -815,9 +833,13 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
if (type == TYPE_INCOMING_PRE_OFFER && failedToStartForegroundService) {
if ((type == TYPE_INCOMING_PRE_OFFER || type == TYPE_INCOMING_RINGING) && failedToStartForegroundService) {
//if (failedToStartForegroundService) {
Log.w("ACL", "DID SOMETHING - foregroundIntent to WebRtcCallActivity for TYPE_INCOMING_PRE_OFFER")
wakeUpDeviceIfLocked()
Log.w("ACL", "About to create foregroundIntent and try to start the WebRtcCallActivity with type TYPE_INCOMING_PRE_OFFER")
// Start an intent for the fullscreen call activity
val foregroundIntent = Intent(this, WebRtcCallActivity::class.java)

@ -37,30 +37,30 @@ class CallNotificationBuilder {
return notificationManager.areNotificationsEnabled()
}
@JvmStatic
fun getFirstCallNotification(context: Context, callerName: String): Notification {
val contentIntent = Intent(context, SettingsActivity::class.java)
val pendingIntent = PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
val titleTxt = context.getSubbedString(R.string.callsMissedCallFrom, NAME_KEY to callerName)
val bodyTxt = context.getSubbedCharSequence(
R.string.callsYouMissedCallPermissions,
NAME_KEY to callerName
)
val builder = NotificationCompat.Builder(context, NotificationChannels.CALLS)
.setSound(null)
.setSmallIcon(R.drawable.ic_baseline_call_24)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentTitle(titleTxt)
.setContentText(bodyTxt)
.setStyle(NotificationCompat.BigTextStyle().bigText(bodyTxt))
.setAutoCancel(true)
return builder.build()
}
// @JvmStatic
// fun getFirstCallNotification(context: Context, callerName: String): Notification {
// val contentIntent = Intent(context, SettingsActivity::class.java)
//
// val pendingIntent = PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
//
// val titleTxt = context.getSubbedString(R.string.callsMissedCallFrom, NAME_KEY to callerName)
// val bodyTxt = context.getSubbedCharSequence(
// R.string.callsYouMissedCallPermissions,
// NAME_KEY to callerName
// )
//
// val builder = NotificationCompat.Builder(context, NotificationChannels.CALLS)
// .setSound(null)
// .setSmallIcon(R.drawable.ic_baseline_call_24)
// .setContentIntent(pendingIntent)
// .setPriority(NotificationCompat.PRIORITY_HIGH)
// .setContentTitle(titleTxt)
// .setContentText(bodyTxt)
// .setStyle(NotificationCompat.BigTextStyle().bigText(bodyTxt))
// .setAutoCancel(true)
//
// return builder.build()
// }
@JvmStatic
fun getCallInProgressNotification(context: Context, type: Int, recipient: Recipient?): Notification {

@ -2,15 +2,18 @@ package org.thoughtcrime.securesms.webrtc
import android.Manifest
import android.annotation.SuppressLint
import android.app.KeyguardManager
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.PowerManager
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.getSystemService
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.coroutineScope
import kotlinx.coroutines.Dispatchers.IO
@ -36,7 +39,7 @@ import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.service.WebRtcCallService
import org.webrtc.IceCandidate
import network.loki.messenger.R
import org.session.libsession.utilities.NonTranslatableStringConstants
class CallMessageProcessor(private val context: Context, private val textSecurePreferences: TextSecurePreferences, lifecycle: Lifecycle, private val storage: StorageProtocol) {
@ -56,11 +59,7 @@ class CallMessageProcessor(private val context: Context, private val textSecureP
fun safeStartForegroundService(context: Context, intent: Intent) {
Log.w("ACL", "Hit safeStartForegroundService for intent action: " + intent.action)
// TODO: This is super-ugly - we're forcing a full-screen intent to wake the device up so we can
// TODO: successfully call `startForegroundService` in the second catch block below. This works
// TODO: even if the device is locked and Session has been closed down - but it's UUUUGLY. Need
// TODO: to find a better way.
showIncomingCallNotification(context)
// If the foreground service crashes then it's possible for one of these intents to
// be started in the background (in which case 'startService' will throw a
@ -71,6 +70,12 @@ class CallMessageProcessor(private val context: Context, private val textSecureP
try { ContextCompat.startForegroundService(context, intent) }
catch (e2: Exception) {
Log.e("Loki", "Unable to start CallMessage intent: ${e2.message}")
// TODO: This is super-ugly - we're forcing a full-screen intent to wake the device up so we can
// TODO: successfully call `startForegroundService` in the second catch block below. This works
// TODO: even if the device is locked and Session has been closed down - but it's UUUUGLY. Need
// TODO: to find a better way.
showIncomingCallNotification(context)
}
}
}
@ -87,8 +92,46 @@ class CallMessageProcessor(private val context: Context, private val textSecureP
notificationManager?.createNotificationChannel(channel)
}
private fun wakeUpDeviceIfLocked(context: Context) {
// Get the KeyguardManager and PowerManager
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
// Check if the phone is locked
val isPhoneLocked = keyguardManager.isKeyguardLocked
// Check if the screen is awake
val isScreenAwake = powerManager.isInteractive
if (!isScreenAwake) {
Log.w("ACL", "CMP: Screen is NOT awake - waking it up!")
val wakeLock = powerManager.newWakeLock(
PowerManager.FULL_WAKE_LOCK or
PowerManager.ACQUIRE_CAUSES_WAKEUP or
PowerManager.ON_AFTER_RELEASE,
"${NonTranslatableStringConstants.APP_NAME}:WakeLock"
)
// Acquire the wake lock to wake up the device
wakeLock.acquire(3000) // Wake up for 3 seconds
} else {
Log.w("ACL", "CMP: Screen is awake - doing nothing")
}
// Dismiss the keyguard
//val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
//val keyguardLock = keyguardManager.newKeyguardLock("MyApp:KeyguardLock")
//keyguardLock.disableKeyguard()
}
@SuppressLint("MissingPermission")
fun showIncomingCallNotification(context: Context) {
wakeUpDeviceIfLocked(context)
createNotificationChannel(context)
val notificationIntent = Intent(context, WebRtcCallActivity::class.java)
@ -108,7 +151,8 @@ class CallMessageProcessor(private val context: Context, private val textSecureP
.setFullScreenIntent(pendingIntent, true)
NotificationManagerCompat.from(context).notify(999, notificationBuilder.build())
} }
}
}
init {
lifecycle.coroutineScope.launch(IO) {

Loading…
Cancel
Save