make contact integration depend on manifest, not flavor
This commit is contained in:
parent
9b832e1285
commit
8e73b7f477
|
@ -62,8 +62,8 @@ public class JabberIdContact extends AbstractPhoneContact {
|
|||
return jid;
|
||||
}
|
||||
|
||||
public static Map<Jid, JabberIdContact> load(Context context) {
|
||||
if (!QuickConversationsService.isFreeOrQuicksyFlavor()
|
||||
public static Map<Jid, JabberIdContact> load(final Context context) {
|
||||
if (!QuickConversationsService.isContactListIntegration(context)
|
||||
|| (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& context.checkSelfPermission(Manifest.permission.READ_CONTACTS)
|
||||
!= PackageManager.PERMISSION_GRANTED)) {
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
package eu.siacs.conversations.services;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import eu.siacs.conversations.BuildConfig;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public abstract class AbstractQuickConversationsService {
|
||||
|
||||
public static final String SMS_RETRIEVED_ACTION =
|
||||
"com.google.android.gms.auth.api.phone.SMS_RETRIEVED";
|
||||
|
||||
public static final String SMS_RETRIEVED_ACTION = "com.google.android.gms.auth.api.phone.SMS_RETRIEVED";
|
||||
private static Boolean declaredReadContacts = null;
|
||||
|
||||
protected final XmppConnectionService service;
|
||||
|
||||
|
@ -30,8 +38,31 @@ public abstract class AbstractQuickConversationsService {
|
|||
return "playstore".equals(BuildConfig.FLAVOR_distribution);
|
||||
}
|
||||
|
||||
public static boolean isFreeOrQuicksyFlavor() {
|
||||
return "free".equals(BuildConfig.FLAVOR_distribution) || "quicksy".equals(BuildConfig.FLAVOR_mode);
|
||||
public static boolean isContactListIntegration(final Context context) {
|
||||
if ("quicksy".equals(BuildConfig.FLAVOR_mode)) {
|
||||
return true;
|
||||
}
|
||||
final var readContacts = AbstractQuickConversationsService.declaredReadContacts;
|
||||
if (readContacts != null) {
|
||||
return Boolean.TRUE.equals(readContacts);
|
||||
}
|
||||
AbstractQuickConversationsService.declaredReadContacts = hasDeclaredReadContacts(context);
|
||||
return AbstractQuickConversationsService.declaredReadContacts;
|
||||
}
|
||||
|
||||
private static boolean hasDeclaredReadContacts(final Context context) {
|
||||
final String[] permissions;
|
||||
try {
|
||||
permissions =
|
||||
context.getPackageManager()
|
||||
.getPackageInfo(
|
||||
context.getPackageName(), PackageManager.GET_PERMISSIONS)
|
||||
.requestedPermissions;
|
||||
} catch (final PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
return Iterables.any(
|
||||
Arrays.asList(permissions), p -> p.equals(Manifest.permission.READ_CONTACTS));
|
||||
}
|
||||
|
||||
public static boolean isQuicksyPlayStore() {
|
||||
|
|
|
@ -1290,7 +1290,7 @@ public class XmppConnectionService extends Service {
|
|||
|
||||
restoreFromDatabase();
|
||||
|
||||
if (QuickConversationsService.isFreeOrQuicksyFlavor()
|
||||
if (QuickConversationsService.isContactListIntegration(this)
|
||||
&& (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
||||
|| ContextCompat.checkSelfPermission(
|
||||
this, Manifest.permission.READ_CONTACTS)
|
||||
|
|
|
@ -120,13 +120,13 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
|
|||
private void checkContactPermissionAndShowAddDialog() {
|
||||
if (hasContactsPermission()) {
|
||||
showAddToPhoneBookDialog();
|
||||
} else if (QuickConversationsService.isFreeOrQuicksyFlavor() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
} else if (QuickConversationsService.isContactListIntegration(this) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_SYNC_CONTACTS);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasContactsPermission() {
|
||||
if (QuickConversationsService.isFreeOrQuicksyFlavor() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (QuickConversationsService.isContactListIntegration(this) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
return checkSelfPermission(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED;
|
||||
} else {
|
||||
return true;
|
||||
|
@ -525,7 +525,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
|
|||
}
|
||||
|
||||
private void onBadgeClick(final View view) {
|
||||
if (QuickConversationsService.isFreeOrQuicksyFlavor()) {
|
||||
if (QuickConversationsService.isContactListIntegration(this)) {
|
||||
final Uri systemAccount = contact.getSystemAccount();
|
||||
if (systemAccount == null) {
|
||||
checkContactPermissionAndShowAddDialog();
|
||||
|
|
|
@ -6,12 +6,14 @@ import android.app.Dialog;
|
|||
import android.app.PendingIntent;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.TextWatcher;
|
||||
|
@ -91,6 +93,8 @@ import eu.siacs.conversations.xmpp.XmppConnection;
|
|||
|
||||
public class StartConversationActivity extends XmppActivity implements XmppConnectionService.OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist, CreatePrivateGroupChatDialog.CreateConferenceDialogListener, JoinConferenceDialog.JoinConferenceDialogListener, SwipeRefreshLayout.OnRefreshListener, CreatePublicChannelDialog.CreatePublicChannelDialogListener {
|
||||
|
||||
private static final String PREF_KEY_CONTACT_INTEGRATION_CONSENT = "contact_list_integration_consent";
|
||||
|
||||
public static final String EXTRA_INVITE_URI = "eu.siacs.conversations.invite_uri";
|
||||
|
||||
private final int REQUEST_SYNC_CONTACTS = 0x28cf;
|
||||
|
@ -761,50 +765,96 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
|||
}
|
||||
|
||||
private void askForContactsPermissions() {
|
||||
if (QuickConversationsService.isFreeOrQuicksyFlavor() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (QuickConversationsService.isContactListIntegration(this)
|
||||
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
if (mRequestedContactsPermission.compareAndSet(false, true)) {
|
||||
if (QuickConversationsService.isQuicksy() || shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS)) {
|
||||
final String consent =
|
||||
PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
|
||||
.getString(PREF_KEY_CONTACT_INTEGRATION_CONSENT, null);
|
||||
final boolean requiresConsent =
|
||||
(QuickConversationsService.isQuicksy()
|
||||
|| QuickConversationsService.isPlayStoreFlavor())
|
||||
&& !"agreed".equals(consent);
|
||||
if (requiresConsent && "declined".equals(consent)) {
|
||||
Log.d(Config.LOGTAG,"not asking for contacts permission because consent has been declined");
|
||||
return;
|
||||
}
|
||||
if (requiresConsent
|
||||
|| shouldShowRequestPermissionRationale(
|
||||
Manifest.permission.READ_CONTACTS)) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
final AtomicBoolean requestPermission = new AtomicBoolean(false);
|
||||
if (QuickConversationsService.isQuicksy()) {
|
||||
builder.setTitle(R.string.quicksy_wants_your_consent);
|
||||
builder.setMessage(Html.fromHtml(getString(R.string.sync_with_contacts_quicksy_static)));
|
||||
builder.setMessage(
|
||||
Html.fromHtml(
|
||||
getString(R.string.sync_with_contacts_quicksy_static)));
|
||||
} else {
|
||||
builder.setTitle(R.string.sync_with_contacts);
|
||||
builder.setMessage(getString(R.string.sync_with_contacts_long, getString(R.string.app_name)));
|
||||
builder.setMessage(
|
||||
getString(
|
||||
R.string.sync_with_contacts_long,
|
||||
getString(R.string.app_name)));
|
||||
}
|
||||
@StringRes int confirmButtonText;
|
||||
if (QuickConversationsService.isConversations()) {
|
||||
confirmButtonText = R.string.next;
|
||||
} else {
|
||||
if (requiresConsent) {
|
||||
confirmButtonText = R.string.agree_and_continue;
|
||||
} else {
|
||||
confirmButtonText = R.string.next;
|
||||
}
|
||||
builder.setPositiveButton(confirmButtonText, (dialog, which) -> {
|
||||
if (requestPermission.compareAndSet(false, true)) {
|
||||
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_SYNC_CONTACTS);
|
||||
}
|
||||
});
|
||||
builder.setOnDismissListener(dialog -> {
|
||||
if (QuickConversationsService.isConversations() && requestPermission.compareAndSet(false, true)) {
|
||||
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_SYNC_CONTACTS);
|
||||
}
|
||||
});
|
||||
if (QuickConversationsService.isQuicksy()) {
|
||||
builder.setNegativeButton(R.string.decline, null);
|
||||
builder.setPositiveButton(
|
||||
confirmButtonText,
|
||||
(dialog, which) -> {
|
||||
if (requiresConsent) {
|
||||
PreferenceManager.getDefaultSharedPreferences(
|
||||
getApplicationContext())
|
||||
.edit()
|
||||
.putString(
|
||||
PREF_KEY_CONTACT_INTEGRATION_CONSENT, "agreed")
|
||||
.apply();
|
||||
}
|
||||
if (requestPermission.compareAndSet(false, true)) {
|
||||
requestPermissions(
|
||||
new String[] {Manifest.permission.READ_CONTACTS},
|
||||
REQUEST_SYNC_CONTACTS);
|
||||
}
|
||||
});
|
||||
if (requiresConsent) {
|
||||
builder.setNegativeButton(R.string.decline, (dialog, which) -> PreferenceManager.getDefaultSharedPreferences(
|
||||
getApplicationContext())
|
||||
.edit()
|
||||
.putString(
|
||||
PREF_KEY_CONTACT_INTEGRATION_CONSENT, "declined")
|
||||
.apply());
|
||||
} else {
|
||||
builder.setOnDismissListener(
|
||||
dialog -> {
|
||||
if (requestPermission.compareAndSet(false, true)) {
|
||||
requestPermissions(
|
||||
new String[] {
|
||||
Manifest.permission.READ_CONTACTS
|
||||
},
|
||||
REQUEST_SYNC_CONTACTS);
|
||||
}
|
||||
});
|
||||
}
|
||||
builder.setCancelable(QuickConversationsService.isQuicksy());
|
||||
builder.setCancelable(requiresConsent);
|
||||
final AlertDialog dialog = builder.create();
|
||||
dialog.setCanceledOnTouchOutside(QuickConversationsService.isQuicksy());
|
||||
dialog.setOnShowListener(dialogInterface -> {
|
||||
final TextView tv = dialog.findViewById(android.R.id.message);
|
||||
if (tv != null) {
|
||||
tv.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
});
|
||||
dialog.setCanceledOnTouchOutside(requiresConsent);
|
||||
dialog.setOnShowListener(
|
||||
dialogInterface -> {
|
||||
final TextView tv = dialog.findViewById(android.R.id.message);
|
||||
if (tv != null) {
|
||||
tv.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
} else {
|
||||
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_SYNC_CONTACTS);
|
||||
requestPermissions(
|
||||
new String[] {Manifest.permission.READ_CONTACTS},
|
||||
REQUEST_SYNC_CONTACTS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -840,7 +890,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
|||
|
||||
@Override
|
||||
protected void onBackendConnected() {
|
||||
if (QuickConversationsService.isFreeOrQuicksyFlavor()
|
||||
if (QuickConversationsService.isContactListIntegration(this)
|
||||
&& (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
||||
|| checkSelfPermission(Manifest.permission.READ_CONTACTS)
|
||||
== PackageManager.PERMISSION_GRANTED)) {
|
||||
|
|
|
@ -10,6 +10,8 @@ import android.os.Build;
|
|||
import android.provider.ContactsContract.Profile;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import eu.siacs.conversations.services.QuickConversationsService;
|
||||
|
||||
public class PhoneHelper {
|
||||
|
@ -20,27 +22,25 @@ public class PhoneHelper {
|
|||
}
|
||||
|
||||
public static Uri getProfilePictureUri(final Context context) {
|
||||
if (!QuickConversationsService.isFreeOrQuicksyFlavor()
|
||||
if (!QuickConversationsService.isContactListIntegration(context)
|
||||
|| (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& context.checkSelfPermission(Manifest.permission.READ_CONTACTS)
|
||||
!= PackageManager.PERMISSION_GRANTED)) {
|
||||
return null;
|
||||
}
|
||||
final String[] projection = new String[] {Profile._ID, Profile.PHOTO_URI};
|
||||
final Cursor cursor;
|
||||
try {
|
||||
cursor =
|
||||
context.getContentResolver()
|
||||
.query(Profile.CONTENT_URI, projection, null, null, null);
|
||||
} catch (Throwable e) {
|
||||
return null;
|
||||
try (final Cursor cursor =
|
||||
context.getContentResolver()
|
||||
.query(Profile.CONTENT_URI, projection, null, null, null)) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
final var photoUri = cursor.getString(1);
|
||||
if (Strings.isNullOrEmpty(photoUri)) {
|
||||
return null;
|
||||
}
|
||||
return Uri.parse(photoUri);
|
||||
}
|
||||
}
|
||||
if (cursor == null) {
|
||||
return null;
|
||||
}
|
||||
final String uri = cursor.moveToFirst() ? cursor.getString(1) : null;
|
||||
cursor.close();
|
||||
return uri == null ? null : Uri.parse(uri);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isEmulator() {
|
||||
|
|
|
@ -518,8 +518,8 @@
|
|||
<string name="no_storage_permission">Grant %1$s access to external storage</string>
|
||||
<string name="no_camera_permission">Grant %1$s access to the camera</string>
|
||||
<string name="quicksy_wants_your_consent">Quicksy asks for your consent to use your data</string>
|
||||
<string name="sync_with_contacts">Synchronize with contacts</string>
|
||||
<string name="sync_with_contacts_long">%1$s wants permission to access your address book to match it with your XMPP contact list.\nThis will display your contacts’ full names and avatars.\n\n%1$s will only read your address book and match it locally without uploading anything to your server.</string>
|
||||
<string name="sync_with_contacts">Contact list integration</string>
|
||||
<string name="sync_with_contacts_long">%1$s processes your contact list locally, on your device, to show you the names and profile pictures for matching contacts on XMPP.\n\nNo contact list data ever leaves your device!</string>
|
||||
<string name="sync_with_contacts_quicksy_static" translatable="false"><![CDATA[Quicksy syncs your contact list in regular intervals to make suggestions about possible contacts, who are already using the app, even when the app is closed or not in use.<br><br>Find more information in our <a href="https://quicksy.im/privacy.htm">Privacy Policy</a>.]]></string>
|
||||
<string name="notify_on_all_messages">Notify on all messages</string>
|
||||
<string name="notify_only_when_highlighted">Notify only when mentioned</string>
|
||||
|
@ -1024,5 +1024,5 @@
|
|||
<string name="report_spam">Report spam</string>
|
||||
<string name="report_spam_and_block">Report spam and block spammer</string>
|
||||
<string name="privacy_policy">Privacy policy</string>
|
||||
<string name="contact_list_integration_not_available">Address book integration is not available</string>
|
||||
<string name="contact_list_integration_not_available">Contact list integration is not available</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue