remove address book integration from Conversations on PlayStore

Daniel Gultsch created

Change summary

build.gradle                                                                         |  2 
src/free/AndroidManifest.xml                                                         |  6 
src/main/AndroidManifest.xml                                                         |  2 
src/main/java/eu/siacs/conversations/android/JabberIdContact.java                    | 61 
src/main/java/eu/siacs/conversations/services/AbstractQuickConversationsService.java |  4 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java             |  6 
src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java                  | 39 
src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java               |  8 
src/main/java/eu/siacs/conversations/utils/PhoneHelper.java                          |  8 
src/main/res/values/strings.xml                                                      |  1 
src/quicksy/AndroidManifest.xml                                                      |  3 
11 files changed, 100 insertions(+), 40 deletions(-)

Detailed changes

build.gradle 🔗

@@ -105,7 +105,7 @@ android {
         def appName = "Conversations"
         resValue "string", "app_name", appName
         buildConfigField "String", "APP_NAME", "\"$appName\""
-        buildConfigField "String", "PRIVACY_POLICY", "null"
+        buildConfigField "String", "PRIVACY_POLICY", "\"https://conversations.im/privacy.html\""
     }
 
     splits {

src/free/AndroidManifest.xml 🔗

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.READ_PROFILE" />
+</manifest>

src/main/AndroidManifest.xml 🔗

@@ -5,8 +5,6 @@
     <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.READ_CONTACTS" />
-    <uses-permission android:name="android.permission.READ_PROFILE" />
     <uses-permission
         android:name="android.permission.READ_PHONE_STATE"
         android:maxSdkVersion="22" />

src/main/java/eu/siacs/conversations/android/JabberIdContact.java 🔗

@@ -8,28 +8,39 @@ import android.os.Build;
 import android.provider.ContactsContract;
 import android.util.Log;
 
+import eu.siacs.conversations.Config;
+import eu.siacs.conversations.services.QuickConversationsService;
+import eu.siacs.conversations.xmpp.Jid;
+
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
-import eu.siacs.conversations.Config;
-import eu.siacs.conversations.xmpp.Jid;
-
 public class JabberIdContact extends AbstractPhoneContact {
 
-    private static final String[] PROJECTION = new String[]{ContactsContract.Data._ID,
-            ContactsContract.Data.DISPLAY_NAME,
-            ContactsContract.Data.PHOTO_URI,
-            ContactsContract.Data.LOOKUP_KEY,
-            ContactsContract.CommonDataKinds.Im.DATA
-    };
-    private static final String SELECTION = ContactsContract.Data.MIMETYPE + "=? AND (" + ContactsContract.CommonDataKinds.Im.PROTOCOL + "=? or (" + ContactsContract.CommonDataKinds.Im.PROTOCOL + "=? and lower(" + ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL + ")=?))";
+    private static final String[] PROJECTION =
+            new String[] {
+                ContactsContract.Data._ID,
+                ContactsContract.Data.DISPLAY_NAME,
+                ContactsContract.Data.PHOTO_URI,
+                ContactsContract.Data.LOOKUP_KEY,
+                ContactsContract.CommonDataKinds.Im.DATA
+            };
+    private static final String SELECTION =
+            ContactsContract.Data.MIMETYPE
+                    + "=? AND ("
+                    + ContactsContract.CommonDataKinds.Im.PROTOCOL
+                    + "=? or ("
+                    + ContactsContract.CommonDataKinds.Im.PROTOCOL
+                    + "=? and lower("
+                    + ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL
+                    + ")=?))";
 
     private static final String[] SELECTION_ARGS = {
-            ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE,
-            String.valueOf(ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER),
-            String.valueOf(ContactsContract.CommonDataKinds.Im.PROTOCOL_CUSTOM),
-            "xmpp"
+        ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE,
+        String.valueOf(ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER),
+        String.valueOf(ContactsContract.CommonDataKinds.Im.PROTOCOL_CUSTOM),
+        "xmpp"
     };
 
     private final Jid jid;
@@ -37,8 +48,12 @@ public class JabberIdContact extends AbstractPhoneContact {
     private JabberIdContact(Cursor cursor) throws IllegalArgumentException {
         super(cursor);
         try {
-            this.jid = Jid.of(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA)));
-        } catch (IllegalArgumentException | NullPointerException e) {
+            this.jid =
+                    Jid.of(
+                            cursor.getString(
+                                    cursor.getColumnIndexOrThrow(
+                                            ContactsContract.CommonDataKinds.Im.DATA)));
+        } catch (final IllegalArgumentException | NullPointerException e) {
             throw new IllegalArgumentException(e);
         }
     }
@@ -48,10 +63,20 @@ public class JabberIdContact extends AbstractPhoneContact {
     }
 
     public static Map<Jid, JabberIdContact> load(Context context) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
+        if (!QuickConversationsService.isFreeOrQuicksyFlavor()
+                || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
+                        && context.checkSelfPermission(Manifest.permission.READ_CONTACTS)
+                                != PackageManager.PERMISSION_GRANTED)) {
             return Collections.emptyMap();
         }
-        try (final Cursor cursor = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, SELECTION_ARGS, null)) {
+        try (final Cursor cursor =
+                context.getContentResolver()
+                        .query(
+                                ContactsContract.Data.CONTENT_URI,
+                                PROJECTION,
+                                SELECTION,
+                                SELECTION_ARGS,
+                                null)) {
             if (cursor == null) {
                 return Collections.emptyMap();
             }

src/main/java/eu/siacs/conversations/services/AbstractQuickConversationsService.java 🔗

@@ -30,6 +30,10 @@ 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 isQuicksyPlayStore() {
         return isQuicksy() && isPlayStoreFlavor();
     }

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -1290,7 +1290,11 @@ public class XmppConnectionService extends Service {
 
         restoreFromDatabase();
 
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
+        if (QuickConversationsService.isFreeOrQuicksyFlavor()
+                && (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
+                        || ContextCompat.checkSelfPermission(
+                                        this, Manifest.permission.READ_CONTACTS)
+                                == PackageManager.PERMISSION_GRANTED)) {
             startContactObserver();
         }
         FILE_OBSERVER_EXECUTOR.execute(fileBackend::deleteHistoricAvatarPath);

src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java 🔗

@@ -46,6 +46,7 @@ import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.entities.Contact;
 import eu.siacs.conversations.entities.ListItem;
 import eu.siacs.conversations.services.AbstractQuickConversationsService;
+import eu.siacs.conversations.services.QuickConversationsService;
 import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
 import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
 import eu.siacs.conversations.ui.adapter.MediaAdapter;
@@ -119,13 +120,13 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
     private void checkContactPermissionAndShowAddDialog() {
         if (hasContactsPermission()) {
             showAddToPhoneBookDialog();
-        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+        } else if (QuickConversationsService.isFreeOrQuicksyFlavor() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_SYNC_CONTACTS);
         }
     }
 
     private boolean hasContactsPermission() {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+        if (QuickConversationsService.isFreeOrQuicksyFlavor() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             return checkSelfPermission(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED;
         } else {
             return true;
@@ -523,18 +524,30 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
         }
     }
 
-    private void onBadgeClick(View view) {
-        final Uri systemAccount = contact.getSystemAccount();
-        if (systemAccount == null) {
-            checkContactPermissionAndShowAddDialog();
-        } else {
-            final Intent intent = new Intent(Intent.ACTION_VIEW);
-            intent.setData(systemAccount);
-            try {
-                startActivity(intent);
-            } catch (final ActivityNotFoundException e) {
-                Toast.makeText(this, R.string.no_application_found_to_view_contact, Toast.LENGTH_SHORT).show();
+    private void onBadgeClick(final View view) {
+        if (QuickConversationsService.isFreeOrQuicksyFlavor()) {
+            final Uri systemAccount = contact.getSystemAccount();
+            if (systemAccount == null) {
+                checkContactPermissionAndShowAddDialog();
+            } else {
+                final Intent intent = new Intent(Intent.ACTION_VIEW);
+                intent.setData(systemAccount);
+                try {
+                    startActivity(intent);
+                } catch (final ActivityNotFoundException e) {
+                    Toast.makeText(
+                                    this,
+                                    R.string.no_application_found_to_view_contact,
+                                    Toast.LENGTH_SHORT)
+                            .show();
+                }
             }
+        } else {
+            Toast.makeText(
+                            this,
+                            R.string.contact_list_integration_not_available,
+                            Toast.LENGTH_SHORT)
+                    .show();
         }
     }
 

src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java 🔗

@@ -761,7 +761,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
     }
 
     private void askForContactsPermissions() {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+        if (QuickConversationsService.isFreeOrQuicksyFlavor() && 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)) {
@@ -840,8 +840,10 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
 
     @Override
     protected void onBackendConnected() {
-
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || checkSelfPermission(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
+        if (QuickConversationsService.isFreeOrQuicksyFlavor()
+                && (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
+                        || checkSelfPermission(Manifest.permission.READ_CONTACTS)
+                                == PackageManager.PERMISSION_GRANTED)) {
             xmppConnectionService.getQuickConversationsService().considerSyncBackground(false);
         }
         if (mPostponedActivityResult != null) {

src/main/java/eu/siacs/conversations/utils/PhoneHelper.java 🔗

@@ -10,6 +10,8 @@ import android.os.Build;
 import android.provider.ContactsContract.Profile;
 import android.provider.Settings;
 
+import eu.siacs.conversations.services.QuickConversationsService;
+
 public class PhoneHelper {
 
     @SuppressLint("HardwareIds")
@@ -18,8 +20,10 @@ public class PhoneHelper {
     }
 
     public static Uri getProfilePictureUri(final Context context) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
-                && context.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
+        if (!QuickConversationsService.isFreeOrQuicksyFlavor()
+                || (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};

src/main/res/values/strings.xml 🔗

@@ -1024,4 +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>
 </resources>

src/quicksy/AndroidManifest.xml 🔗

@@ -6,6 +6,9 @@
         android:name="android.permission.REQUEST_INSTALL_PACKAGES"
         tools:node="remove" />
 
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.READ_PROFILE" />
+
     <application
         android:icon="@mipmap/new_launcher"
         tools:ignore="GoogleAppIndexingWarning"