UnifiedPush: send unregistered to apps when 'none' account is selected

This commit is contained in:
Daniel Gultsch 2023-12-05 10:59:50 +01:00
parent 20c179c1a1
commit 1a83c290a2
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
3 changed files with 88 additions and 0 deletions

View file

@ -16,6 +16,7 @@ import com.google.common.collect.ImmutableList;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import eu.siacs.conversations.Config;
@ -129,6 +130,23 @@ public class UnifiedPushDatabase extends SQLiteOpenHelper {
return null;
}
public List<PushTarget> deletePushTargets() {
final SQLiteDatabase sqLiteDatabase = getReadableDatabase();
final ImmutableList.Builder<PushTarget> builder = new ImmutableList.Builder<>();
try (final Cursor cursor = sqLiteDatabase.query("push",new String[]{"application","instance"},null,null,null,null,null)) {
if (cursor != null && cursor.moveToFirst()) {
builder.add(new PushTarget(
cursor.getString(cursor.getColumnIndexOrThrow("application")),
cursor.getString(cursor.getColumnIndexOrThrow("instance"))));
}
} catch (final Exception e) {
Log.d(Config.LOGTAG,"unable to retrieve push targets",e);
return builder.build();
}
sqLiteDatabase.delete("push",null,null);
return builder.build();
}
public boolean hasEndpoints(final UnifiedPushBroker.Transport transport) {
final SQLiteDatabase sqLiteDatabase = getReadableDatabase();
try (final Cursor cursor =

View file

@ -10,10 +10,18 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.util.Log;
import androidx.annotation.NonNull;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.io.BaseEncoding;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
@ -239,6 +247,9 @@ public class UnifiedPushBroker {
public boolean reconfigurePushDistributor() {
final boolean enabled = getTransport().isPresent();
setUnifiedPushDistributorEnabled(enabled);
if (!enabled) {
unregisterCurrentPushTargets();
}
return enabled;
}
@ -261,6 +272,43 @@ public class UnifiedPushBroker {
}
}
private void unregisterCurrentPushTargets() {
final var future = deletePushTargets();
Futures.addCallback(
future,
new FutureCallback<>() {
@Override
public void onSuccess(
final List<UnifiedPushDatabase.PushTarget> pushTargets) {
broadcastUnregistered(pushTargets);
}
@Override
public void onFailure(@NonNull Throwable throwable) {
Log.d(
Config.LOGTAG,
"could not delete endpoints after UnifiedPushDistributor was disabled");
}
},
MoreExecutors.directExecutor());
}
private ListenableFuture<List<UnifiedPushDatabase.PushTarget>> deletePushTargets() {
return Futures.submit(() -> UnifiedPushDatabase.getInstance(service).deletePushTargets(),SCHEDULER);
}
private void broadcastUnregistered(final List<UnifiedPushDatabase.PushTarget> pushTargets) {
for(final UnifiedPushDatabase.PushTarget pushTarget : pushTargets) {
Log.d(Config.LOGTAG,"sending unregistered to "+pushTarget);
broadcastUnregistered(pushTarget);
}
}
private void broadcastUnregistered(final UnifiedPushDatabase.PushTarget pushTarget) {
final var intent = unregisteredIntent(pushTarget);
service.sendBroadcast(intent);
}
public boolean processPushMessage(
final Account account, final Jid transport, final Element push) {
final String instance = push.getAttribute("instance");
@ -355,6 +403,7 @@ public class UnifiedPushBroker {
updateIntent.putExtra("token", target.instance);
updateIntent.putExtra("bytesMessage", payload);
updateIntent.putExtra("message", new String(payload, StandardCharsets.UTF_8));
// TODO add distributor verification?
service.sendBroadcast(updateIntent);
}
@ -379,6 +428,19 @@ public class UnifiedPushBroker {
return intent;
}
private Intent unregisteredIntent(final UnifiedPushDatabase.PushTarget pushTarget) {
final Intent intent = new Intent(UnifiedPushDistributor.ACTION_UNREGISTERED);
intent.setPackage(pushTarget.application);
intent.putExtra("token", pushTarget.instance);
final var distributorVerificationIntent = new Intent();
distributorVerificationIntent.setPackage(service.getPackageName());
final var pendingIntent =
PendingIntent.getBroadcast(
service, 0, distributorVerificationIntent, PendingIntent.FLAG_IMMUTABLE);
intent.putExtra("distributor", pendingIntent);
return intent;
}
public void rebroadcastEndpoint(final Messenger messenger, final String instance, final Transport transport) {
final UnifiedPushDatabase unifiedPushDatabase = UnifiedPushDatabase.getInstance(service);
final UnifiedPushDatabase.ApplicationEndpoint endpoint =

View file

@ -29,8 +29,15 @@ import eu.siacs.conversations.utils.Compatibility;
public class UnifiedPushDistributor extends BroadcastReceiver {
// distributor actions (these are actios used for connector->distributor broadcasts)
// we, the distributor, have a broadcast receiver listening for those actions
public static final String ACTION_REGISTER = "org.unifiedpush.android.distributor.REGISTER";
public static final String ACTION_UNREGISTER = "org.unifiedpush.android.distributor.UNREGISTER";
// connector actions (these are actions used for distributor->connector broadcasts)
public static final String ACTION_UNREGISTERED = "org.unifiedpush.android.connector.UNREGISTERED";
public static final String ACTION_BYTE_MESSAGE =
"org.unifiedpush.android.distributor.feature.BYTES_MESSAGE";
public static final String ACTION_REGISTRATION_FAILED =
@ -172,6 +179,7 @@ public class UnifiedPushDistributor extends BroadcastReceiver {
if (unifiedPushDatabase.deleteInstance(instance)) {
quickLog(context, String.format("successfully unregistered token %s from UnifiedPushed (application requested unregister)", instance));
Log.d(Config.LOGTAG, "successfully removed " + instance + " from UnifiedPush");
// TODO send UNREGISTERED broadcast back to app?!
}
}