From c16ea5ad67bf454158b364dec2f26c95a879c350 Mon Sep 17 00:00:00 2001 From: Yorke Lee Date: Tue, 19 May 2015 15:51:01 -0700 Subject: Handle runtime permissions in Dialer Conditionally disable the following features if the required permissions are not available: 1) Display of all contacts 2) Display of speed dial 3) Caller ID in call log 4) Import/export contacts 5) Conversion of People.CONTENT_ITEM_TYPE and Phones.CONTENT_ITEM_TYPE into a phone number (via DIAL intent) 6) UndemoteOutgoingCallReceiver 7) Contact Search 8) Contact lookup in call detail activity 9) Nearby places search Bug: 20266292 Change-Id: I6d26902acb0eac407ae7bc18c11aa6ec57299506 --- src/com/android/dialer/DialerApplication.java | 2 - src/com/android/dialer/DialtactsActivity.java | 16 +++++--- src/com/android/dialer/calllog/CallLogAdapter.java | 11 +++-- .../android/dialer/calllog/ContactInfoHelper.java | 4 ++ .../dialer/contactinfo/ContactInfoCache.java | 12 +----- .../dialer/database/DialerDatabaseHelper.java | 5 ++- .../android/dialer/dialpad/DialpadFragment.java | 4 ++ .../dialer/dialpad/SmartDialCursorLoader.java | 5 +++ .../interactions/UndemoteOutgoingCallReceiver.java | 10 +++-- .../android/dialer/list/AllContactsFragment.java | 12 ++++++ .../dialer/list/EmptyContactsListAdapter.java | 47 ++++++++++++++++++++++ src/com/android/dialer/list/SearchFragment.java | 11 +++++ src/com/android/dialer/list/SpeedDialFragment.java | 13 ++++-- 13 files changed, 124 insertions(+), 28 deletions(-) create mode 100644 src/com/android/dialer/list/EmptyContactsListAdapter.java (limited to 'src') diff --git a/src/com/android/dialer/DialerApplication.java b/src/com/android/dialer/DialerApplication.java index 7bc3bb4d3..b177d8336 100644 --- a/src/com/android/dialer/DialerApplication.java +++ b/src/com/android/dialer/DialerApplication.java @@ -19,14 +19,12 @@ package com.android.dialer; import android.app.Application; import android.os.Trace; -import com.android.contacts.common.ContactPhotoManager; import com.android.contacts.common.extensions.ExtensionsFactory; import com.android.contacts.commonbind.analytics.AnalyticsUtil; public class DialerApplication extends Application { private static final String TAG = "DialerApplication"; - private ContactPhotoManager mContactPhotoManager; @Override public void onCreate() { diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java index 56d5ad171..e240cf0aa 100644 --- a/src/com/android/dialer/DialtactsActivity.java +++ b/src/com/android/dialer/DialtactsActivity.java @@ -29,12 +29,10 @@ import android.content.res.Resources; import android.net.Uri; import android.os.Bundle; import android.os.Trace; -import android.provider.ContactsContract.Intents; import android.speech.RecognizerIntent; import android.support.v4.view.ViewPager; import android.telecom.PhoneAccount; import android.telecom.TelecomManager; -import android.telephony.TelephonyManager; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; @@ -63,6 +61,7 @@ import com.android.contacts.common.dialog.ClearFrequentsDialog; import com.android.contacts.common.interactions.ImportExportDialogFragment; import com.android.contacts.common.interactions.TouchPointManager; import com.android.contacts.common.list.OnPhoneNumberPickerActionListener; +import com.android.contacts.common.util.PermissionsUtil; import com.android.contacts.common.widget.FloatingActionButtonController; import com.android.contacts.commonbind.analytics.AnalyticsUtil; import com.android.dialer.calllog.CallLogActivity; @@ -248,11 +247,16 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O @Override public void show() { + final boolean hasContactsPermission = + PermissionsUtil.hasContactsPermissions(DialtactsActivity.this); final Menu menu = getMenu(); final MenuItem clearFrequents = menu.findItem(R.id.menu_clear_frequents); clearFrequents.setVisible(mListsFragment != null && mListsFragment.getSpeedDialFragment() != null && - mListsFragment.getSpeedDialFragment().hasFrequents()); + mListsFragment.getSpeedDialFragment().hasFrequents() && hasContactsPermission); + + menu.findItem(R.id.menu_import_export).setVisible(hasContactsPermission); + menu.findItem(R.id.menu_add_contact).setVisible(hasContactsPermission); super.show(); } } @@ -359,6 +363,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O protected void onCreate(Bundle savedInstanceState) { Trace.beginSection(TAG + " onCreate"); super.onCreate(savedInstanceState); + mFirstLaunch = true; final Resources resources = getResources(); @@ -818,7 +823,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O protected OptionsPopupMenu buildOptionsMenu(View invoker) { final OptionsPopupMenu popupMenu = new OptionsPopupMenu(this, invoker); popupMenu.inflate(R.menu.dialtacts_options); - final Menu menu = popupMenu.getMenu(); popupMenu.setOnMenuItemClickListener(this); return popupMenu; } @@ -829,7 +833,9 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O mSearchView.setText(mPendingSearchViewQuery); mPendingSearchViewQuery = null; } - mActionBarController.restoreActionBarOffset(); + if (mActionBarController != null) { + mActionBarController.restoreActionBarOffset(); + } return false; } diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java index 608475e0b..5c57c1854 100644 --- a/src/com/android/dialer/calllog/CallLogAdapter.java +++ b/src/com/android/dialer/calllog/CallLogAdapter.java @@ -34,6 +34,7 @@ import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.accessibility.AccessibilityEvent; +import com.android.contacts.common.util.PermissionsUtil; import com.android.dialer.PhoneCallDetails; import com.android.dialer.PhoneCallDetailsHelper; import com.android.dialer.R; @@ -184,8 +185,9 @@ public class CallLogAdapter extends GroupingListAdapter public boolean onPreDraw() { // We only wanted to listen for the first draw (and this is it). unregisterPreDrawListener(); - - mContactInfoCache.start(); + if (PermissionsUtil.hasContactsPermissions(mContext)) { + mContactInfoCache.start(); + } return true; } @@ -205,6 +207,9 @@ public class CallLogAdapter extends GroupingListAdapter mContactInfoCache = new ContactInfoCache( mContactInfoHelper, mOnContactInfoChangedListener); + if (!PermissionsUtil.hasContactsPermissions(context)) { + mContactInfoCache.disableRequestProcessing(); + } Resources resources = mContext.getResources(); CallTypeHelper callTypeHelper = new CallTypeHelper(resources); @@ -534,7 +539,7 @@ public class CallLogAdapter extends GroupingListAdapter @VisibleForTesting void disableRequestProcessingForTest() { // TODO: Remove this and test the cache directly. - mContactInfoCache.disableRequestProcessingForTest(); + mContactInfoCache.disableRequestProcessing(); } @VisibleForTesting diff --git a/src/com/android/dialer/calllog/ContactInfoHelper.java b/src/com/android/dialer/calllog/ContactInfoHelper.java index 38c9bba87..9a660e1ae 100644 --- a/src/com/android/dialer/calllog/ContactInfoHelper.java +++ b/src/com/android/dialer/calllog/ContactInfoHelper.java @@ -30,6 +30,7 @@ import android.text.TextUtils; import android.util.Log; import com.android.contacts.common.util.Constants; +import com.android.contacts.common.util.PermissionsUtil; import com.android.contacts.common.util.PhoneNumberHelper; import com.android.contacts.common.util.UriUtils; import com.android.dialer.service.CachedNumberLookupService; @@ -162,6 +163,9 @@ public class ContactInfoHelper { if (uri == null) { return null; } + if (!PermissionsUtil.hasContactsPermissions(mContext)) { + return ContactInfo.EMPTY; + } final ContactInfo info; Cursor phonesCursor = mContext.getContentResolver().query(uri, PhoneQuery._PROJECTION, null, null, null); diff --git a/src/com/android/dialer/contactinfo/ContactInfoCache.java b/src/com/android/dialer/contactinfo/ContactInfoCache.java index 2bb0f1e95..568f48886 100644 --- a/src/com/android/dialer/contactinfo/ContactInfoCache.java +++ b/src/com/android/dialer/contactinfo/ContactInfoCache.java @@ -51,7 +51,7 @@ public class ContactInfoCache { private volatile boolean mDone = false; public QueryThread() { - super("CallLogAdapter.QueryThread"); + super("ContactInfoCache.QueryThread"); } public void stopProcessing() { @@ -316,20 +316,12 @@ public class ContactInfoCache { && TextUtils.equals(callLogInfo.label, info.label); } - /** - * Can be set to true by tests to disable processing of requests. - */ - @VisibleForTesting private volatile boolean mRequestProcessingDisabled = false; /** * Sets whether processing of requests for contact details should be enabled. - * - * This method should be called in tests to disable such processing of requests when not - * needed. */ - @VisibleForTesting - public void disableRequestProcessingForTest() { + public void disableRequestProcessing() { mRequestProcessingDisabled = true; } diff --git a/src/com/android/dialer/database/DialerDatabaseHelper.java b/src/com/android/dialer/database/DialerDatabaseHelper.java index 2177878c6..eec24f5bc 100644 --- a/src/com/android/dialer/database/DialerDatabaseHelper.java +++ b/src/com/android/dialer/database/DialerDatabaseHelper.java @@ -36,6 +36,7 @@ import android.provider.ContactsContract.Directory; import android.text.TextUtils; import android.util.Log; +import com.android.contacts.common.util.PermissionsUtil; import com.android.contacts.common.util.StopWatch; import com.android.dialer.R; import com.android.dialer.dialpad.SmartDialNameMatcher; @@ -485,7 +486,9 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper { * Starts the database upgrade process in the background. */ public void startSmartDialUpdateThread() { - new SmartDialUpdateAsyncTask().execute(); + if (PermissionsUtil.hasContactsPermissions(mContext)) { + new SmartDialUpdateAsyncTask().execute(); + } } private class SmartDialUpdateAsyncTask extends AsyncTask { diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java index 8d27c143b..de1d44f89 100644 --- a/src/com/android/dialer/dialpad/DialpadFragment.java +++ b/src/com/android/dialer/dialpad/DialpadFragment.java @@ -70,6 +70,7 @@ import android.widget.TextView; import com.android.contacts.common.ContactsUtils; import com.android.contacts.common.GeoUtil; +import com.android.contacts.common.util.PermissionsUtil; import com.android.contacts.common.util.PhoneNumberFormatter; import com.android.contacts.common.util.StopWatch; import com.android.contacts.common.widget.FloatingActionButtonController; @@ -441,6 +442,9 @@ public class DialpadFragment extends Fragment setFormattedDigits(converted, null); return true; } else { + if (!PermissionsUtil.hasContactsPermissions(getActivity())) { + return false; + } String type = intent.getType(); if (People.CONTENT_ITEM_TYPE.equals(type) || Phones.CONTENT_ITEM_TYPE.equals(type)) { diff --git a/src/com/android/dialer/dialpad/SmartDialCursorLoader.java b/src/com/android/dialer/dialpad/SmartDialCursorLoader.java index 372692eae..f83f18cd7 100644 --- a/src/com/android/dialer/dialpad/SmartDialCursorLoader.java +++ b/src/com/android/dialer/dialpad/SmartDialCursorLoader.java @@ -25,6 +25,7 @@ import android.net.Uri; import android.util.Log; import com.android.contacts.common.list.PhoneNumberListAdapter.PhoneQuery; +import com.android.contacts.common.util.PermissionsUtil; import com.android.dialer.database.DialerDatabaseHelper; import com.android.dialer.database.DialerDatabaseHelper.ContactNumber; import com.android.dialerbind.DatabaseHelperManager; @@ -77,6 +78,10 @@ public class SmartDialCursorLoader extends AsyncTaskLoader { Log.v(TAG, "Load in background " + mQuery); } + if (!PermissionsUtil.hasContactsPermissions(mContext)) { + return new MatrixCursor(PhoneQuery.PROJECTION_PRIMARY); + } + /** Loads results from the database helper. */ final DialerDatabaseHelper dialerDatabaseHelper = DatabaseHelperManager.getDatabaseHelper( mContext); diff --git a/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java b/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java index 960a31bc3..fd3d512f0 100644 --- a/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java +++ b/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java @@ -27,6 +27,8 @@ import android.provider.ContactsContract.PhoneLookup; import android.provider.ContactsContract.PinnedPositions; import android.text.TextUtils; +import com.android.contacts.common.util.PermissionsUtil; + /** * This broadcast receiver is used to listen to outgoing calls and undemote formerly demoted * contacts if a phone call is made to a phone number belonging to that contact. @@ -39,12 +41,15 @@ public class UndemoteOutgoingCallReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, Intent intent) { + if (!PermissionsUtil.hasContactsPermissions(context)) { + return; + } if (intent != null && Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) { final String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); if (TextUtils.isEmpty(number)) { return; } - final Thread thread = new Thread() { + new Thread() { @Override public void run() { final long id = getContactIdFromPhoneNumber(context, number); @@ -52,8 +57,7 @@ public class UndemoteOutgoingCallReceiver extends BroadcastReceiver { undemoteContactWithId(context, id); } } - }; - thread.start(); + }.start(); } } diff --git a/src/com/android/dialer/list/AllContactsFragment.java b/src/com/android/dialer/list/AllContactsFragment.java index 94efc4869..eaa5cc808 100644 --- a/src/com/android/dialer/list/AllContactsFragment.java +++ b/src/com/android/dialer/list/AllContactsFragment.java @@ -29,6 +29,7 @@ import com.android.contacts.common.list.ContactEntryListAdapter; import com.android.contacts.common.list.ContactEntryListFragment; import com.android.contacts.common.list.ContactListFilter; import com.android.contacts.common.list.DefaultContactListAdapter; +import com.android.contacts.common.util.PermissionsUtil; import com.android.contacts.common.util.ViewUtil; import com.android.dialer.R; import com.android.dialer.util.DialerUtils; @@ -59,8 +60,19 @@ public class AllContactsFragment extends ContactEntryListFragment