Use existing contact type for our linked entry. Add test to sample app.
Fixes #9431 Closes #9434 Co-authored-by: swatts <github@stargw.net>
This commit is contained in:
parent
4098f77e08
commit
0e4187b062
62 changed files with 287 additions and 113 deletions
|
@ -13,7 +13,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|||
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
/**
|
||||
* This should be used whenever we want to prompt the user to block/unblock a recipient.
|
||||
|
|
|
@ -85,7 +85,7 @@ import org.thoughtcrime.securesms.util.UsernameUtil;
|
|||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.adapter.FixedViewsAdapter;
|
||||
import org.thoughtcrime.securesms.util.adapter.RecyclerViewConcatenateAdapterStickyHeader;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -33,7 +33,7 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
|||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
|||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
|
|
@ -12,7 +12,7 @@ import org.thoughtcrime.securesms.crypto.ReentrantSessionLock;
|
|||
import org.thoughtcrime.securesms.crypto.storage.SignalIdentityKeyStore;
|
||||
import org.thoughtcrime.securesms.database.model.IdentityRecord;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.whispersystems.signalservice.api.SignalSessionLock;
|
||||
|
||||
import java.util.List;
|
||||
|
|
|
@ -11,7 +11,7 @@ import org.thoughtcrime.securesms.crypto.ReentrantSessionLock;
|
|||
import org.thoughtcrime.securesms.database.IdentityDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.IdentityRecord;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.whispersystems.signalservice.api.SignalSessionLock;
|
||||
|
||||
import java.util.List;
|
||||
|
|
|
@ -9,6 +9,7 @@ import androidx.lifecycle.ViewModelProvider
|
|||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.signal.core.util.AppUtil
|
||||
import org.signal.core.util.concurrent.SignalExecutors
|
||||
import org.signal.core.util.concurrent.SimpleTask
|
||||
import org.signal.ringrtc.CallManager
|
||||
import org.thoughtcrime.securesms.BuildConfig
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
@ -34,7 +35,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore
|
|||
import org.thoughtcrime.securesms.payments.DataExportUtil
|
||||
import org.thoughtcrime.securesms.util.ConversationUtil
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask
|
||||
import java.util.Optional
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.math.max
|
||||
|
|
|
@ -13,6 +13,7 @@ import androidx.core.app.ShareCompat
|
|||
import androidx.core.view.drawToBitmap
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import org.signal.core.util.concurrent.SimpleTask
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
|
||||
|
@ -25,7 +26,6 @@ import org.thoughtcrime.securesms.database.model.DonationReceiptRecord
|
|||
import org.thoughtcrime.securesms.payments.FiatMoneyUtil
|
||||
import org.thoughtcrime.securesms.providers.BlobProvider
|
||||
import org.thoughtcrime.securesms.util.DateUtils
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.util.Locale
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.thoughtcrime.securesms.database.SignalDatabase;
|
|||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.util.MessageRecordUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
|
|
@ -15,7 +15,7 @@ import org.thoughtcrime.securesms.database.ThreadDatabase;
|
|||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.notifications.MarkReadReceiver;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ object ContactDiscovery {
|
|||
|
||||
private const val MESSAGE_MIMETYPE = "vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact"
|
||||
private const val CALL_MIMETYPE = "vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.call"
|
||||
private const val CONTACT_TAG = "__TS"
|
||||
|
||||
@JvmStatic
|
||||
@Throws(IOException::class)
|
||||
|
@ -54,7 +55,8 @@ object ContactDiscovery {
|
|||
callPrompt = { e164 -> context.getString(R.string.ContactsDatabase_signal_call_s, e164) },
|
||||
e164Formatter = { number -> PhoneNumberFormatter.get(context).format(number) },
|
||||
messageMimetype = MESSAGE_MIMETYPE,
|
||||
callMimetype = CALL_MIMETYPE
|
||||
callMimetype = CALL_MIMETYPE,
|
||||
syncTag = CONTACT_TAG
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,7 +121,6 @@ import org.thoughtcrime.securesms.groups.ui.managegroup.dialogs.GroupDescription
|
|||
import org.thoughtcrime.securesms.groups.ui.migration.GroupsV1MigrationInfoBottomSheetDialogFragment;
|
||||
import org.thoughtcrime.securesms.groups.v2.GroupBlockJoinRequestResult;
|
||||
import org.thoughtcrime.securesms.groups.v2.GroupDescriptionUtil;
|
||||
import org.thoughtcrime.securesms.groups.v2.GroupManagementRepository;
|
||||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceViewOnceOpenJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
|
@ -170,7 +169,7 @@ import org.thoughtcrime.securesms.util.Util;
|
|||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.WindowUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
|
||||
import org.thoughtcrime.securesms.verify.VerifyIdentityActivity;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
|
||||
|
|
|
@ -33,7 +33,7 @@ import org.thoughtcrime.securesms.profiles.spoofing.ReviewUtil;
|
|||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.AsynchronousCallback;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -294,7 +294,7 @@ import org.thoughtcrime.securesms.util.WindowUtil;
|
|||
import org.thoughtcrime.securesms.util.concurrent.AssertedSuccessListener;
|
||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SettableFuture;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.Stub;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaperDimLevelUtil;
|
||||
|
|
|
@ -151,7 +151,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.WindowUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.task.SnackbarAsyncTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
import org.thoughtcrime.securesms.util.views.Stub;
|
||||
|
|
|
@ -5,11 +5,11 @@ import android.graphics.Bitmap
|
|||
import android.graphics.BitmapFactory
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.annotation.WorkerThread
|
||||
import org.signal.core.util.concurrent.SimpleTask
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority
|
||||
import org.thoughtcrime.securesms.util.ListenableFutureTask
|
||||
import org.thoughtcrime.securesms.util.SoftHashMap
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.os.SystemClock
|
|||
import androidx.annotation.MainThread
|
||||
import org.signal.core.util.ThreadUtil
|
||||
import org.signal.core.util.concurrent.SignalExecutors
|
||||
import org.signal.core.util.concurrent.SimpleTask
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiDrawInfo
|
||||
import org.thoughtcrime.securesms.emoji.protos.JumbomojiPack
|
||||
|
@ -14,7 +15,6 @@ import org.thoughtcrime.securesms.jobmanager.impl.AutoDownloadEmojiConstraint
|
|||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.util.ListenableFutureTask
|
||||
import org.thoughtcrime.securesms.util.SoftHashMap
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask
|
||||
import java.io.IOException
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.ExecutionException
|
||||
|
|
|
@ -19,7 +19,7 @@ import org.thoughtcrime.securesms.groups.GroupId;
|
|||
import org.thoughtcrime.securesms.groups.GroupManager;
|
||||
import org.thoughtcrime.securesms.groups.ui.chooseadmin.ChooseNewAdminActivity;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -15,7 +15,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.whispersystems.signalservice.api.util.Preconditions;
|
||||
|
||||
import java.util.List;
|
||||
|
|
|
@ -15,7 +15,7 @@ import org.thoughtcrime.securesms.groups.LiveGroup;
|
|||
import org.thoughtcrime.securesms.groups.ui.GroupChangeResult;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.thoughtcrime.securesms.util.FeatureFlags;
|
|||
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.thoughtcrime.securesms.R;
|
|||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry;
|
||||
import org.thoughtcrime.securesms.util.DefaultValueLiveData;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
|
|
@ -21,7 +21,7 @@ import org.thoughtcrime.securesms.groups.MembershipNotSuitableForV2Exception;
|
|||
import org.thoughtcrime.securesms.groups.ui.GroupMemberListView;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -18,7 +18,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
|||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.thoughtcrime.securesms.database.SignalDatabase;
|
|||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
|
|
@ -9,7 +9,7 @@ import org.signal.core.util.logging.Log;
|
|||
import org.signal.libsignal.protocol.InvalidKeyException;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.pin.PinState;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -15,6 +15,7 @@ import androidx.fragment.app.viewModels
|
|||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavDestination
|
||||
import androidx.navigation.findNavController
|
||||
import org.signal.core.util.concurrent.SimpleTask
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.MainActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
@ -36,7 +37,6 @@ import org.thoughtcrime.securesms.util.BottomSheetUtil
|
|||
import org.thoughtcrime.securesms.util.TopToastPopup
|
||||
import org.thoughtcrime.securesms.util.TopToastPopup.Companion.show
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask
|
||||
import org.thoughtcrime.securesms.util.views.Stub
|
||||
import org.thoughtcrime.securesms.util.visible
|
||||
import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState
|
||||
|
|
|
@ -47,7 +47,7 @@ import org.thoughtcrime.securesms.database.SignalDatabase;
|
|||
import org.thoughtcrime.securesms.database.loaders.MediaLoader;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
|
@ -14,7 +14,7 @@ import org.thoughtcrime.securesms.attachments.AttachmentId;
|
|||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.mms.PartUriParser;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ import org.thoughtcrime.securesms.util.FeatureFlags;
|
|||
import org.thoughtcrime.securesms.util.MemoryFileDescriptor;
|
||||
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.video.VideoUtil;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
|
|
|
@ -22,7 +22,7 @@ import org.thoughtcrime.securesms.payments.preferences.model.PayeeParcelable;
|
|||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;
|
||||
|
||||
import java.util.Optional;
|
||||
|
|
|
@ -8,7 +8,7 @@ import androidx.core.content.ContextCompat;
|
|||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
|
||||
public final class PinOptOutDialog {
|
||||
|
|
|
@ -11,7 +11,7 @@ import androidx.appcompat.app.AlertDialog;
|
|||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
|
|
@ -19,7 +19,7 @@ import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
|||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
|
|
@ -42,7 +42,7 @@ import org.thoughtcrime.securesms.profiles.manage.EditProfileNameFragment;
|
|||
import org.thoughtcrime.securesms.providers.BlobProvider;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;
|
||||
import org.thoughtcrime.securesms.util.text.AfterTextChanged;
|
||||
import org.thoughtcrime.securesms.util.views.LearnMoreTextView;
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
|||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.registration.RegistrationUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.groups.ui.GroupChangeErrorCallback;
|
|||
import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
|
|
@ -9,7 +9,7 @@ import org.signal.core.util.logging.Log;
|
|||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.registration.viewmodel.RegistrationViewModel;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.util.CommunicationActions;
|
|||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||
import org.thoughtcrime.securesms.util.SupportEmailUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -56,7 +56,7 @@ import org.thoughtcrime.securesms.service.LocalBackupListener;
|
|||
import org.thoughtcrime.securesms.util.BackupUtil;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -61,7 +61,7 @@ import org.thoughtcrime.securesms.util.StorageUtil;
|
|||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.ThrottledDebouncer;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
|
|
@ -33,7 +33,7 @@ import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage;
|
|||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.util.MessageUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
|
|
@ -67,7 +67,7 @@ import org.thoughtcrime.securesms.util.FeatureFlags;
|
|||
import org.thoughtcrime.securesms.util.LifecycleDisposable;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
|
@ -37,7 +37,7 @@ import org.thoughtcrime.securesms.permissions.Permissions;
|
|||
import org.thoughtcrime.securesms.proxy.ProxyBottomSheetFragment;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -33,7 +33,7 @@ import org.thoughtcrime.securesms.sms.OutgoingIdentityVerifiedMessage;
|
|||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SettableFuture;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.whispersystems.signalservice.api.SignalSessionLock;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
|
|
|
@ -63,7 +63,7 @@ import org.thoughtcrime.securesms.util.FeatureFlags;
|
|||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.whispersystems.signalservice.api.SignalSessionLock;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
|
|
@ -11,7 +11,7 @@ import org.signal.core.util.logging.Log;
|
|||
import org.thoughtcrime.securesms.WebRtcCallActivity;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
|
||||
public class VoiceCallShare extends Activity {
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ android {
|
|||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
minSdkVersion 19
|
||||
minSdkVersion 21
|
||||
targetSdkVersion TARGET_SDK
|
||||
multiDexEnabled true
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
android:name=".ContactsActivity"
|
||||
android:exported="false" />
|
||||
|
||||
|
||||
<service
|
||||
android:name=".AccountAuthenticatorService"
|
||||
android:exported="true">
|
||||
|
@ -34,6 +33,21 @@
|
|||
android:name="android.accounts.AccountAuthenticator"
|
||||
android:resource="@xml/authenticator" />
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name=".ContactsSyncAdapterService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.SyncAdapter" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.content.SyncAdapter"
|
||||
android:resource="@xml/syncadapter" />
|
||||
<meta-data
|
||||
android:name="android.provider.CONTACTS_STRUCTURE"
|
||||
android:resource="@xml/contactsformat" />
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,33 @@
|
|||
package org.signal.contactstest
|
||||
|
||||
import android.accounts.Account
|
||||
import android.content.AbstractThreadedSyncAdapter
|
||||
import android.content.ContentProviderClient
|
||||
import android.content.Context
|
||||
import android.content.SyncResult
|
||||
import android.os.Bundle
|
||||
import org.signal.core.util.logging.Log
|
||||
|
||||
class ContactsSyncAdapter(context: Context?, autoInitialize: Boolean) : AbstractThreadedSyncAdapter(context, autoInitialize) {
|
||||
override fun onPerformSync(
|
||||
account: Account,
|
||||
extras: Bundle,
|
||||
authority: String,
|
||||
provider: ContentProviderClient,
|
||||
syncResult: SyncResult
|
||||
) {
|
||||
Log.i(TAG, "onPerformSync()")
|
||||
}
|
||||
|
||||
override fun onSyncCanceled() {
|
||||
Log.w(TAG, "onSyncCanceled()")
|
||||
}
|
||||
|
||||
override fun onSyncCanceled(thread: Thread) {
|
||||
Log.w(TAG, "onSyncCanceled($thread)")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(ContactsSyncAdapter::class.java)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.signal.contactstest
|
||||
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.os.IBinder
|
||||
|
||||
class ContactsSyncAdapterService : Service() {
|
||||
@Synchronized
|
||||
override fun onCreate() {
|
||||
if (syncAdapter == null) {
|
||||
syncAdapter = ContactsSyncAdapter(this, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent): IBinder? {
|
||||
return syncAdapter!!.syncAdapterBinder
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var syncAdapter: ContactsSyncAdapter? = null
|
||||
}
|
||||
}
|
|
@ -1,13 +1,19 @@
|
|||
package org.signal.contactstest
|
||||
|
||||
import android.Manifest
|
||||
import android.accounts.Account
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.telephony.PhoneNumberUtils
|
||||
import android.widget.Button
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import org.signal.contacts.ContactLinkConfiguration
|
||||
import org.signal.contacts.SystemContactsRepository
|
||||
import org.signal.core.util.concurrent.SimpleTask
|
||||
import org.signal.core.util.logging.Log
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
@ -22,15 +28,64 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
if (hasPermission(Manifest.permission.READ_CONTACTS) && hasPermission(Manifest.permission.WRITE_CONTACTS)) {
|
||||
Log.i(TAG, "Already have permission.")
|
||||
startActivity(Intent(this, ContactsActivity::class.java))
|
||||
finish()
|
||||
return
|
||||
findViewById<Button>(R.id.contact_list_button).setOnClickListener { v ->
|
||||
if (hasPermission(Manifest.permission.READ_CONTACTS) && hasPermission(Manifest.permission.WRITE_CONTACTS)) {
|
||||
startActivity(Intent(this, ContactsActivity::class.java))
|
||||
finish()
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS), PERMISSION_CODE)
|
||||
}
|
||||
}
|
||||
|
||||
findViewById<Button>(R.id.permission_button).setOnClickListener { v ->
|
||||
requestPermissions(arrayOf(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS), PERMISSION_CODE)
|
||||
findViewById<Button>(R.id.link_contacts_button).setOnClickListener { v ->
|
||||
if (hasPermission(Manifest.permission.READ_CONTACTS) && hasPermission(Manifest.permission.WRITE_CONTACTS)) {
|
||||
SimpleTask.run({
|
||||
val allE164s: Set<String> = SystemContactsRepository.getAllDisplayNumbers(this).map { PhoneNumberUtils.formatNumberToE164(it, "US") }.toSet()
|
||||
val account: Account = SystemContactsRepository.getOrCreateSystemAccount(this, BuildConfig.APPLICATION_ID, "Contact Test") ?: return@run false
|
||||
|
||||
SystemContactsRepository.addMessageAndCallLinksToContacts(
|
||||
context = this,
|
||||
config = buildLinkConfig(account),
|
||||
targetE164s = allE164s,
|
||||
removeIfMissing = true
|
||||
)
|
||||
|
||||
return@run true
|
||||
}, { success ->
|
||||
if (success) {
|
||||
Toast.makeText(this, "Success!", Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(this, "Failed to create account!", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS), PERMISSION_CODE)
|
||||
}
|
||||
}
|
||||
|
||||
findViewById<Button>(R.id.unlink_contact_button).setOnClickListener { v ->
|
||||
if (hasPermission(Manifest.permission.READ_CONTACTS) && hasPermission(Manifest.permission.WRITE_CONTACTS)) {
|
||||
SimpleTask.run({
|
||||
val account: Account = SystemContactsRepository.getOrCreateSystemAccount(this, BuildConfig.APPLICATION_ID, "Contact Test") ?: return@run false
|
||||
|
||||
SystemContactsRepository.addMessageAndCallLinksToContacts(
|
||||
context = this,
|
||||
config = buildLinkConfig(account),
|
||||
targetE164s = emptySet(),
|
||||
removeIfMissing = true
|
||||
)
|
||||
|
||||
return@run true
|
||||
}, { success ->
|
||||
if (success) {
|
||||
Toast.makeText(this, "Success!", Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(this, "Failed to create account!", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS), PERMISSION_CODE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,4 +103,17 @@ class MainActivity : AppCompatActivity() {
|
|||
private fun hasPermission(permission: String): Boolean {
|
||||
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
|
||||
private fun buildLinkConfig(account: Account): ContactLinkConfiguration {
|
||||
return ContactLinkConfiguration(
|
||||
account = account,
|
||||
appName = "Contact Test",
|
||||
messagePrompt = { "(Test) Message $it" },
|
||||
callPrompt = { "(Test) Call $it" },
|
||||
e164Formatter = { PhoneNumberUtils.formatNumberToE164(it, "US") },
|
||||
messageMimetype = "vnd.android.cursor.item/vnd.org.signal.contacts.test.message",
|
||||
callMimetype = "vnd.android.cursor.item/vnd.org.signal.contacts.test.call",
|
||||
syncTag = "__TEST"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -7,13 +7,34 @@
|
|||
tools:context=".MainActivity">
|
||||
|
||||
<Button
|
||||
android:id="@+id/permission_button"
|
||||
android:id="@+id/contact_list_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Permissions"
|
||||
android:text="Contact List"
|
||||
app:layout_constraintBottom_toTopOf="@id/link_contacts_button"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/link_contacts_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Link Contacts"
|
||||
app:layout_constraintBottom_toTopOf="@id/unlink_contact_button"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/contact_list_button" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/unlink_contact_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Unlink Contacts"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toBottomOf="@id/link_contacts_button" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -29,7 +29,6 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:fontFamily="monospace"
|
||||
tools:text="Spider-Man"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/contact_photo"
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
android:id="@+id/given_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="monospace"
|
||||
tools:text="Spider-Man"/>
|
||||
|
||||
<TextView
|
||||
|
@ -37,7 +36,6 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:fontFamily="monospace"
|
||||
tools:text="Spider-Man"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
|
|
16
contacts/app/src/main/res/xml/contactsformat.xml
Normal file
16
contacts/app/src/main/res/xml/contactsformat.xml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ContactsSource
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<ContactsDataKind
|
||||
android:detailColumn="data3"
|
||||
android:detailSocialSummary="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:mimeType="vnd.android.cursor.item/vnd.org.signal.contacts.test.message"
|
||||
android:summaryColumn="data2" />
|
||||
<ContactsDataKind
|
||||
android:detailColumn="data3"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:mimeType="vnd.android.cursor.item/vnd.org.signal.contacts.test.call"
|
||||
android:summaryColumn="data2" />
|
||||
</ContactsSource>
|
9
contacts/app/src/main/res/xml/syncadapter.xml
Normal file
9
contacts/app/src/main/res/xml/syncadapter.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<sync-adapter
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:accountType="org.signal.contactstest"
|
||||
android:allowParallelSyncs="false"
|
||||
android:contentAuthority="com.android.contacts"
|
||||
android:isAlwaysSyncable="true"
|
||||
android:supportsUploading="true"
|
||||
android:userVisible="true" />
|
|
@ -20,4 +20,5 @@ class ContactLinkConfiguration(
|
|||
val e164Formatter: (String) -> String,
|
||||
val messageMimetype: String,
|
||||
val callMimetype: String,
|
||||
val syncTag: String
|
||||
)
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.util.Objects
|
|||
object SystemContactsRepository {
|
||||
|
||||
private val TAG = Log.tag(SystemContactsRepository::class.java)
|
||||
private const val SYNC_TAG = "__TS"
|
||||
|
||||
private const val FIELD_FORMATTED_PHONE = ContactsContract.RawContacts.SYNC1
|
||||
private const val FIELD_TAG = ContactsContract.Data.SYNC2
|
||||
|
@ -146,7 +145,7 @@ object SystemContactsRepository {
|
|||
removeIfMissing: Boolean
|
||||
) {
|
||||
val operations: ArrayList<ContentProviderOperation> = ArrayList()
|
||||
val currentLinkedContacts: Map<String, RawContactDetails> = getRawContactsByE164(context, config.account, config.e164Formatter)
|
||||
val currentLinkedContacts: Map<String, LinkedContactDetails> = getLinkedContactsByE164(context, config.account, config.e164Formatter)
|
||||
|
||||
val targetChunks: List<List<String>> = targetE164s.chunked(50).toList()
|
||||
for (targetChunk in targetChunks) {
|
||||
|
@ -157,15 +156,8 @@ object SystemContactsRepository {
|
|||
Log.i(TAG, "Adding number: $target")
|
||||
operations += buildAddRawContactOperations(
|
||||
operationIndex = operations.size,
|
||||
account = config.account,
|
||||
appName = config.appName,
|
||||
messagePrompt = config.messagePrompt,
|
||||
callPrompt = config.callPrompt,
|
||||
formattedPhone = systemContactInfo.formattedPhone,
|
||||
displayName = systemContactInfo.displayName,
|
||||
aggregateId = systemContactInfo.rawContactId,
|
||||
messageMimetype = config.messageMimetype,
|
||||
callMimetype = config.callMimetype
|
||||
linkConfig = config,
|
||||
systemContactInfo = systemContactInfo
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +173,7 @@ object SystemContactsRepository {
|
|||
if (!targetE164s.contains(e164)) {
|
||||
if (removeIfMissing) {
|
||||
Log.i(TAG, "Removing number: $e164")
|
||||
removeTextSecureRawContact(operations, config.account, details.id)
|
||||
removeLinkedContact(operations, config.account, details.id)
|
||||
}
|
||||
} else if (!Objects.equals(details.rawDisplayName, details.aggregateDisplayName)) {
|
||||
Log.i(TAG, "Updating display name: $e164")
|
||||
|
@ -372,15 +364,8 @@ object SystemContactsRepository {
|
|||
|
||||
private fun buildAddRawContactOperations(
|
||||
operationIndex: Int,
|
||||
account: Account,
|
||||
appName: String,
|
||||
messagePrompt: (String) -> String,
|
||||
callPrompt: (String) -> String,
|
||||
formattedPhone: String,
|
||||
displayName: String?,
|
||||
aggregateId: Long,
|
||||
messageMimetype: String,
|
||||
callMimetype: String
|
||||
linkConfig: ContactLinkConfiguration,
|
||||
systemContactInfo: SystemContactInfo
|
||||
): List<ContentProviderOperation> {
|
||||
val dataUri = ContactsContract.Data.CONTENT_URI.buildUpon()
|
||||
.appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
|
||||
|
@ -388,59 +373,60 @@ object SystemContactsRepository {
|
|||
|
||||
return listOf(
|
||||
ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
|
||||
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, account.name)
|
||||
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type)
|
||||
.withValue(FIELD_FORMATTED_PHONE, formattedPhone)
|
||||
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, linkConfig.account.name)
|
||||
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, linkConfig.account.type)
|
||||
.withValue(FIELD_FORMATTED_PHONE, systemContactInfo.formattedPhone)
|
||||
.withValue(FIELD_SUPPORTS_VOICE, true.toString())
|
||||
.build(),
|
||||
|
||||
ContentProviderOperation.newInsert(dataUri)
|
||||
.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, operationIndex)
|
||||
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName)
|
||||
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, systemContactInfo.displayName)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
|
||||
.build(),
|
||||
|
||||
ContentProviderOperation.newInsert(dataUri)
|
||||
.withValueBackReference(ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID, operationIndex)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
|
||||
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, formattedPhone)
|
||||
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_OTHER)
|
||||
.withValue(FIELD_TAG, SYNC_TAG)
|
||||
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, systemContactInfo.formattedPhone)
|
||||
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, systemContactInfo.type)
|
||||
.withValue(FIELD_TAG, linkConfig.syncTag)
|
||||
.build(),
|
||||
|
||||
ContentProviderOperation.newInsert(dataUri)
|
||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, operationIndex)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, messageMimetype)
|
||||
.withValue(ContactsContract.Data.DATA1, formattedPhone)
|
||||
.withValue(ContactsContract.Data.DATA2, appName)
|
||||
.withValue(ContactsContract.Data.DATA3, messagePrompt(formattedPhone))
|
||||
.withValue(ContactsContract.Data.MIMETYPE, linkConfig.messageMimetype)
|
||||
.withValue(ContactsContract.Data.DATA1, systemContactInfo.formattedPhone)
|
||||
.withValue(ContactsContract.Data.DATA2, linkConfig.appName)
|
||||
.withValue(ContactsContract.Data.DATA3, linkConfig.messagePrompt(systemContactInfo.formattedPhone))
|
||||
.withYieldAllowed(true)
|
||||
.build(),
|
||||
|
||||
ContentProviderOperation.newInsert(dataUri)
|
||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, operationIndex)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, callMimetype)
|
||||
.withValue(ContactsContract.Data.DATA1, formattedPhone)
|
||||
.withValue(ContactsContract.Data.DATA2, appName)
|
||||
.withValue(ContactsContract.Data.DATA3, callPrompt(formattedPhone))
|
||||
.withValue(ContactsContract.Data.MIMETYPE, linkConfig.callMimetype)
|
||||
.withValue(ContactsContract.Data.DATA1, systemContactInfo.formattedPhone)
|
||||
.withValue(ContactsContract.Data.DATA2, linkConfig.appName)
|
||||
.withValue(ContactsContract.Data.DATA3, linkConfig.callPrompt(systemContactInfo.formattedPhone))
|
||||
.withYieldAllowed(true)
|
||||
.build(),
|
||||
|
||||
ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI)
|
||||
.withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, aggregateId)
|
||||
.withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, systemContactInfo.rawContactId)
|
||||
.withValueBackReference(ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, operationIndex)
|
||||
.withValue(ContactsContract.AggregationExceptions.TYPE, ContactsContract.AggregationExceptions.TYPE_KEEP_TOGETHER)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
private fun removeTextSecureRawContact(operations: MutableList<ContentProviderOperation>, account: Account, rowId: Long) {
|
||||
private fun removeLinkedContact(operations: MutableList<ContentProviderOperation>, account: Account, rowId: Long) {
|
||||
operations.add(
|
||||
ContentProviderOperation.newDelete(
|
||||
ContactsContract.RawContacts.CONTENT_URI.buildUpon()
|
||||
.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, account.name)
|
||||
.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type)
|
||||
.appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build()
|
||||
.appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
|
||||
.build()
|
||||
)
|
||||
.withYieldAllowed(true)
|
||||
.withSelection("${BaseColumns._ID} = ?", SqlUtil.buildArgs(rowId))
|
||||
|
@ -448,7 +434,7 @@ object SystemContactsRepository {
|
|||
)
|
||||
}
|
||||
|
||||
private fun getRawContactsByE164(context: Context, account: Account, e164Formatter: (String) -> String): Map<String, RawContactDetails> {
|
||||
private fun getLinkedContactsByE164(context: Context, account: Account, e164Formatter: (String) -> String): Map<String, LinkedContactDetails> {
|
||||
val currentContactsUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon()
|
||||
.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, account.name)
|
||||
.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type).build()
|
||||
|
@ -461,7 +447,7 @@ object SystemContactsRepository {
|
|||
ContactsContract.RawContacts.DISPLAY_NAME_SOURCE
|
||||
)
|
||||
|
||||
val contactsDetails: MutableMap<String, RawContactDetails> = HashMap()
|
||||
val contactsDetails: MutableMap<String, LinkedContactDetails> = HashMap()
|
||||
|
||||
context.contentResolver.query(currentContactsUri, projection, null, null, null)?.use { cursor ->
|
||||
while (cursor.moveToNext()) {
|
||||
|
@ -470,7 +456,7 @@ object SystemContactsRepository {
|
|||
if (formattedPhone != null) {
|
||||
val e164 = e164Formatter(formattedPhone)
|
||||
|
||||
contactsDetails[e164] = RawContactDetails(
|
||||
contactsDetails[e164] = LinkedContactDetails(
|
||||
id = cursor.requireLong(BaseColumns._ID),
|
||||
supportsVoice = cursor.requireString(FIELD_SUPPORTS_VOICE),
|
||||
rawDisplayName = cursor.requireString(ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY),
|
||||
|
@ -489,7 +475,8 @@ object SystemContactsRepository {
|
|||
val projection = arrayOf(
|
||||
ContactsContract.PhoneLookup.NUMBER,
|
||||
ContactsContract.PhoneLookup._ID,
|
||||
ContactsContract.PhoneLookup.DISPLAY_NAME
|
||||
ContactsContract.PhoneLookup.DISPLAY_NAME,
|
||||
ContactsContract.PhoneLookup.TYPE
|
||||
)
|
||||
|
||||
context.contentResolver.query(uri, projection, null, null, null)?.use { contactCursor ->
|
||||
|
@ -503,7 +490,8 @@ object SystemContactsRepository {
|
|||
return SystemContactInfo(
|
||||
displayName = contactCursor.requireString(ContactsContract.PhoneLookup.DISPLAY_NAME),
|
||||
formattedPhone = systemNumber,
|
||||
rawContactId = idCursor.requireLong(ContactsContract.RawContacts._ID)
|
||||
rawContactId = idCursor.requireLong(ContactsContract.RawContacts._ID),
|
||||
type = contactCursor.requireInt(ContactsContract.PhoneLookup.TYPE)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -530,7 +518,8 @@ object SystemContactsRepository {
|
|||
|
||||
interface ContactIterator : Iterator<ContactDetails>, Closeable {
|
||||
@Throws
|
||||
override fun close() {}
|
||||
override fun close() {
|
||||
}
|
||||
}
|
||||
|
||||
private class EmptyContactIterator : ContactIterator {
|
||||
|
@ -718,7 +707,7 @@ object SystemContactsRepository {
|
|||
val country: String?
|
||||
)
|
||||
|
||||
private data class RawContactDetails(
|
||||
private data class LinkedContactDetails(
|
||||
val id: Long,
|
||||
val supportsVoice: String?,
|
||||
val rawDisplayName: String?,
|
||||
|
@ -729,7 +718,8 @@ object SystemContactsRepository {
|
|||
private data class SystemContactInfo(
|
||||
val displayName: String?,
|
||||
val formattedPhone: String,
|
||||
val rawContactId: Long
|
||||
val rawContactId: Long,
|
||||
val type: Int
|
||||
)
|
||||
|
||||
private data class StructuredName(val givenName: String?, val familyName: String?)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package org.thoughtcrime.securesms.util.concurrent;
|
||||
package org.signal.core.util.concurrent;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
Loading…
Add table
Reference in a new issue