Messaging: Let there be lambdas

Change-Id: Iee1fc46c92ea9159abb10d92d34baee937bdee0c
This commit is contained in:
Michael W
2024-12-26 14:55:12 +01:00
parent c1b4aa4dfe
commit d43b6ff1c4
84 changed files with 991 additions and 1697 deletions
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1085,12 +1086,7 @@ public class BugleNotifications {
OBSERVABLE_CONVERSATION_NOTIFICATION_VOLUME);
// Stop the sound after five seconds to handle continuous ringtones
ThreadUtil.getMainThreadHandler().postDelayed(new Runnable() {
@Override
public void run() {
player.stop();
}
}, 5000);
ThreadUtil.getMainThreadHandler().postDelayed(player::stop, 5000);
}
public static boolean isWearCompanionAppInstalled() {
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -235,17 +236,14 @@ public class DataModelImpl extends DataModel {
}
private void createConnectivityUtilForEachActiveSubscription() {
PhoneUtils.forEachActiveSubscription(new PhoneUtils.SubscriptionRunnable() {
@Override
public void runForSubscription(int subId) {
// Create the ConnectivityUtil instance for given subId if absent.
if (subId <= ParticipantData.DEFAULT_SELF_SUB_ID) {
subId = PhoneUtils.getDefault().getDefaultSmsSubscriptionId();
}
if (!sConnectivityUtilInstanceCacheN.containsKey(subId)) {
sConnectivityUtilInstanceCacheN.put(
subId, new ConnectivityUtil(mContext, subId));
}
PhoneUtils.forEachActiveSubscription(subId -> {
// Create the ConnectivityUtil instance for given subId if absent.
if (subId <= ParticipantData.DEFAULT_SELF_SUB_ID) {
subId = PhoneUtils.getDefault().getDefaultSmsSubscriptionId();
}
if (!sConnectivityUtilInstanceCacheN.containsKey(subId)) {
sConnectivityUtilInstanceCacheN.put(
subId, new ConnectivityUtil(mContext, subId));
}
});
}
@@ -67,12 +67,7 @@ public class DatabaseWrapper {
// track transaction on a per thread basis
private static final ThreadLocal<Stack<TransactionData>> sTransactionDepth =
new ThreadLocal<Stack<TransactionData>>() {
@Override
public Stack<TransactionData> initialValue() {
return new Stack<TransactionData>();
}
};
ThreadLocal.withInitial(() -> new Stack<TransactionData>());
private static final String[] sFormatStrings = new String[] {
"took %d ms to %s",
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +26,6 @@ import com.android.messaging.util.ContactUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
* A cursor builder that takes the frequent contacts cursor and aggregate it with the all contacts
@@ -155,37 +155,34 @@ public class FrequentContactsCursorBuilder {
// Now we have a list of rows containing frequent contacts in alphabetical order.
// Therefore, sort all the rows according to their actual ranks in the frequents list.
Collections.sort(rows, new Comparator<Object[]>() {
@Override
public int compare(final Object[] lhs, final Object[] rhs) {
final String lookupKeyLhs = (String) lhs[ContactUtil.INDEX_LOOKUP_KEY];
final String lookupKeyRhs = (String) rhs[ContactUtil.INDEX_LOOKUP_KEY];
Assert.isTrue(lookupKeyToRankMap.containsKey(lookupKeyLhs) &&
lookupKeyToRankMap.containsKey(lookupKeyRhs));
final int rankLhs = lookupKeyToRankMap.get(lookupKeyLhs);
final int rankRhs = lookupKeyToRankMap.get(lookupKeyRhs);
if (rankLhs < rankRhs) {
Collections.sort(rows, (lhs, rhs) -> {
final String lookupKeyLhs = (String) lhs[ContactUtil.INDEX_LOOKUP_KEY];
final String lookupKeyRhs = (String) rhs[ContactUtil.INDEX_LOOKUP_KEY];
Assert.isTrue(lookupKeyToRankMap.containsKey(lookupKeyLhs) &&
lookupKeyToRankMap.containsKey(lookupKeyRhs));
final int rankLhs = lookupKeyToRankMap.get(lookupKeyLhs);
final int rankRhs = lookupKeyToRankMap.get(lookupKeyRhs);
if (rankLhs < rankRhs) {
return -1;
} else if (rankLhs > rankRhs) {
return 1;
} else {
// Same rank, so it's two contact records for the same contact.
// Perform secondary sorting on the phone type. Always place
// mobile before everything else.
final int phoneTypeLhs = (int) lhs[ContactUtil.INDEX_PHONE_EMAIL_TYPE];
final int phoneTypeRhs = (int) rhs[ContactUtil.INDEX_PHONE_EMAIL_TYPE];
if (phoneTypeLhs == Phone.TYPE_MOBILE &&
phoneTypeRhs == Phone.TYPE_MOBILE) {
return 0;
} else if (phoneTypeLhs == Phone.TYPE_MOBILE) {
return -1;
} else if (rankLhs > rankRhs) {
} else if (phoneTypeRhs == Phone.TYPE_MOBILE) {
return 1;
} else {
// Same rank, so it's two contact records for the same contact.
// Perform secondary sorting on the phone type. Always place
// mobile before everything else.
final int phoneTypeLhs = (int) lhs[ContactUtil.INDEX_PHONE_EMAIL_TYPE];
final int phoneTypeRhs = (int) rhs[ContactUtil.INDEX_PHONE_EMAIL_TYPE];
if (phoneTypeLhs == Phone.TYPE_MOBILE &&
phoneTypeRhs == Phone.TYPE_MOBILE) {
return 0;
} else if (phoneTypeLhs == Phone.TYPE_MOBILE) {
return -1;
} else if (phoneTypeRhs == Phone.TYPE_MOBILE) {
return 1;
} else {
// Use the default sort order, i.e. sort by phoneType value.
return phoneTypeLhs < phoneTypeRhs ? -1 :
(phoneTypeLhs == phoneTypeRhs ? 0 : 1);
}
// Use the default sort order, i.e. sort by phoneType value.
return phoneTypeLhs < phoneTypeRhs ? -1 :
(phoneTypeLhs == phoneTypeRhs ? 0 : 1);
}
}
});
@@ -96,20 +96,13 @@ public class ParticipantRefresh {
private static volatile boolean sObserverInitialized = false;
private static final Object sLock = new Object();
private static final AtomicBoolean sFullRefreshScheduled = new AtomicBoolean(false);
private static final Runnable sFullRefreshRunnable = new Runnable() {
@Override
public void run() {
final boolean oldScheduled = sFullRefreshScheduled.getAndSet(false);
Assert.isTrue(oldScheduled);
refreshParticipants(REFRESH_MODE_FULL);
}
private static final Runnable sFullRefreshRunnable = () -> {
final boolean oldScheduled = sFullRefreshScheduled.getAndSet(false);
Assert.isTrue(oldScheduled);
refreshParticipants(REFRESH_MODE_FULL);
};
private static final Runnable sSelfOnlyRefreshRunnable = new Runnable() {
@Override
public void run() {
private static final Runnable sSelfOnlyRefreshRunnable = () ->
refreshParticipants(REFRESH_MODE_SELF_ONLY);
}
};
/**
* A customized content resolver to track contact changes.
@@ -303,24 +303,21 @@ public class ActionMonitor {
}
if (completedListener != null) {
// Marshal to UI thread
mHandler.post(new Runnable() {
@Override
public void run() {
ActionCompletedListener listener = null;
synchronized (mLock) {
if (mCompletedListener != null) {
listener = mCompletedListener;
}
mCompletedListener = null;
mHandler.post(() -> {
ActionCompletedListener listener = null;
synchronized (mLock) {
if (mCompletedListener != null) {
listener = mCompletedListener;
}
if (listener != null) {
if (succeeded) {
listener.onActionSucceeded(ActionMonitor.this,
action, mData, result);
} else {
listener.onActionFailed(ActionMonitor.this,
action, mData, result);
}
mCompletedListener = null;
}
if (listener != null) {
if (succeeded) {
listener.onActionSucceeded(ActionMonitor.this,
action, mData, result);
} else {
listener.onActionFailed(ActionMonitor.this,
action, mData, result);
}
}
});
@@ -372,21 +369,18 @@ public class ActionMonitor {
}
if (executedListener != null) {
// Marshal to UI thread
mHandler.post(new Runnable() {
@Override
public void run() {
ActionExecutedListener listener = null;
synchronized (mLock) {
if (mExecutedListener != null) {
listener = mExecutedListener;
mExecutedListener = null;
}
}
if (listener != null) {
listener.onActionExecuted(ActionMonitor.this,
action, mData, result);
mHandler.post(() -> {
ActionExecutedListener listener = null;
synchronized (mLock) {
if (mExecutedListener != null) {
listener = mExecutedListener;
mExecutedListener = null;
}
}
if (listener != null) {
listener.onActionExecuted(ActionMonitor.this,
action, mData, result);
}
});
}
}
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -117,22 +118,13 @@ public class BugleActionToasts {
}
private static void showToast(final int messageResId) {
ThreadUtil.getMainThreadHandler().post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),
getApplicationContext().getString(messageResId), Toast.LENGTH_LONG).show();
}
});
ThreadUtil.getMainThreadHandler().post(() -> Toast.makeText(getApplicationContext(),
getApplicationContext().getString(messageResId), Toast.LENGTH_LONG).show());
}
private static void showToast(final String message) {
ThreadUtil.getMainThreadHandler().post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
});
ThreadUtil.getMainThreadHandler().post(() ->
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show());
}
private static Context getApplicationContext() {
@@ -61,18 +61,15 @@ public class ProcessPendingMessagesAction extends Action implements Parcelable {
private static final String KEY_SUB_ID = "sub_id";
public static void processFirstPendingMessage() {
PhoneUtils.forEachActiveSubscription(new PhoneUtils.SubscriptionRunnable() {
@Override
public void runForSubscription(final int subId) {
// Clear any pending alarms or connectivity events
unregister(subId);
// Clear retry count
setRetry(0, subId);
// Start action
final ProcessPendingMessagesAction action = new ProcessPendingMessagesAction();
action.actionParameters.putInt(KEY_SUB_ID, subId);
action.start();
}
PhoneUtils.forEachActiveSubscription(subId -> {
// Clear any pending alarms or connectivity events
unregister(subId);
// Clear retry count
setRetry(0, subId);
// Start action
final ProcessPendingMessagesAction action = new ProcessPendingMessagesAction();
action.actionParameters.putInt(KEY_SUB_ID, subId);
action.start();
});
}
@@ -114,23 +111,20 @@ public class ProcessPendingMessagesAction extends Action implements Parcelable {
}
if (getHavePendingMessages(subId) || scheduleAlarm) {
// Still have a pending message that needs to be queued for processing
final ConnectivityListener listener = new ConnectivityListener() {
@Override
public void onPhoneStateChanged(final int serviceState) {
if (serviceState == ServiceState.STATE_IN_SERVICE) {
LogUtil.i(TAG, "ProcessPendingMessagesAction: Now connected for subId "
+ subId + ", starting action");
final ConnectivityListener listener = serviceState -> {
if (serviceState == ServiceState.STATE_IN_SERVICE) {
LogUtil.i(TAG, "ProcessPendingMessagesAction: Now connected for subId "
+ subId + ", starting action");
// Clear any pending alarms or connectivity events but leave attempt count
// alone
unregister(subId);
// Clear any pending alarms or connectivity events but leave attempt count
// alone
unregister(subId);
// Start action
final ProcessPendingMessagesAction action =
new ProcessPendingMessagesAction();
action.actionParameters.putInt(KEY_SUB_ID, subId);
action.start();
}
// Start action
final ProcessPendingMessagesAction action =
new ProcessPendingMessagesAction();
action.actionParameters.putInt(KEY_SUB_ID, subId);
action.start();
}
};
// Read and increment attempt number from shared prefs
@@ -627,21 +627,18 @@ public class ConversationData extends BindableData {
}
if (ContactUtil.hasReadContactsPermission()) {
SafeAsyncTask.executeOnThreadPool(new Runnable() {
@Override
public void run() {
final DataUsageStatUpdater updater = new DataUsageStatUpdater(
Factory.get().getApplicationContext());
try {
if (!phones.isEmpty()) {
updater.updateWithPhoneNumber(phones);
}
if (!emails.isEmpty()) {
updater.updateWithAddress(emails);
}
} catch (final SQLiteFullException ex) {
LogUtil.w(TAG, "Unable to update contact", ex);
SafeAsyncTask.executeOnThreadPool(() -> {
final DataUsageStatUpdater updater = new DataUsageStatUpdater(
Factory.get().getApplicationContext());
try {
if (!phones.isEmpty()) {
updater.updateWithPhoneNumber(phones);
}
if (!emails.isEmpty()) {
updater.updateWithAddress(emails);
}
} catch (final SQLiteFullException ex) {
LogUtil.w(TAG, "Unable to update contact", ex);
}
});
}
@@ -445,13 +445,9 @@ public class MessagePartData implements Parcelable {
public void destroyAsync() {
final Uri contentUri = shouldDestroy();
if (contentUri != null) {
SafeAsyncTask.executeOnThreadPool(new Runnable() {
@Override
public void run() {
SafeAsyncTask.executeOnThreadPool(() ->
Factory.get().getApplicationContext().getContentResolver().delete(
contentUri, null, null);
}
});
contentUri, null, null));
}
}
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +21,6 @@ import android.database.Cursor;
import androidx.collection.ArrayMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -61,15 +61,11 @@ public class SelfParticipantsData {
list.add(self);
}
}
Collections.sort(
list,
new Comparator() {
public int compare(Object o1, Object o2) {
int slotId1 = ((ParticipantData) o1).getSlotId();
int slotId2 = ((ParticipantData) o2).getSlotId();
return slotId1 > slotId2 ? 1 : -1;
}
});
list.sort((Comparator) (o1, o2) -> {
int slotId1 = ((ParticipantData) o1).getSlotId();
int slotId2 = ((ParticipantData) o2).getSlotId();
return slotId1 > slotId2 ? 1 : -1;
});
return list;
}
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +28,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
/**
* <p>Loads and maintains a set of in-memory LRU caches for different types of media resources.
@@ -104,13 +104,10 @@ public class MediaResourceManager {
// These tasks are run on a single worker thread with low priority so as not to contend with the
// media loading tasks.
private static final Executor MEDIA_BACKGROUND_EXECUTOR = Executors.newSingleThreadExecutor(
new ThreadFactory() {
@Override
public Thread newThread(final Runnable runnable) {
final Thread encodingThread = new Thread(runnable);
encodingThread.setPriority(Thread.MIN_PRIORITY);
return encodingThread;
}
runnable -> {
final Thread encodingThread = new Thread(runnable);
encodingThread.setPriority(Thread.MIN_PRIORITY);
return encodingThread;
});
/**
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -71,13 +72,9 @@ public class VCardResourceEntry {
void close() {
// If the avatar image was temporarily saved in the scratch folder, remove that.
if (MediaScratchFileProvider.isMediaScratchSpaceUri(mAvatarUri)) {
SafeAsyncTask.executeOnThreadPool(new Runnable() {
@Override
public void run() {
SafeAsyncTask.executeOnThreadPool(() ->
Factory.get().getApplicationContext().getContentResolver().delete(
mAvatarUri, null, null);
}
});
mAvatarUri, null, null));
}
}