diff options
author | Yorke Lee <yorkelee@google.com> | 2015-07-16 11:36:07 -0700 |
---|---|---|
committer | Yorke Lee <yorkelee@google.com> | 2015-07-17 10:23:33 -0700 |
commit | 575ae388961252a771488c357e425fca191594b2 (patch) | |
tree | 81126e76d811d650cd1b44a59380a14ceb703891 /src | |
parent | 3cf92c747c54fa44240be5ba78cbc8eb6e3b8cd5 (diff) |
Add permission prompts for contacts and dialpad search
Update the following fragments to handle denied permissions
-Contacts Search (Contacts and Location)
-Dialpad Search (Phone)
Tweak and remove some of the onTouch listener logic as they are
no longer valid with the new UI. Instead of intercepting the touches
when the query is empty and returning to the main dialer activity,
allow the fragments to remain on screen if the permission request
UI is showing.
Modify signature of onEmptyViewActionButtonClicked to remove unused
permissions parameter.
Bug: 22174668
Change-Id: I96d00f2ab45df936dca602ac025f723638ac02c4
Diffstat (limited to 'src')
9 files changed, 163 insertions, 31 deletions
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java index 85197a530..98f34b57d 100644 --- a/src/com/android/dialer/DialtactsActivity.java +++ b/src/com/android/dialer/DialtactsActivity.java @@ -103,6 +103,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O DialpadFragment.OnDialpadQueryChangedListener, OnListFragmentScrolledListener, CallLogFragment.HostInterface, + DialpadFragment.HostInterface, ListsFragment.HostInterface, SpeedDialFragment.HostInterface, SearchFragment.HostInterface, @@ -486,8 +487,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O } }); - setupActivityOverlay(); - Trace.endSection(); Trace.beginSection(TAG + " initialize smart dialing"); @@ -497,19 +496,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O Trace.endSection(); } - private void setupActivityOverlay() { - final View activityOverlay = findViewById(R.id.activity_overlay); - activityOverlay.setOnTouchListener(new OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - if (!mIsDialpadShown) { - maybeExitSearchUi(); - } - return false; - } - }); - } - @Override protected void onResume() { Trace.beginSection(TAG + " onResume"); @@ -1147,7 +1133,16 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O } catch (Exception ignored) { // Skip any exceptions for this piece of code } + } + @Override + public boolean onDialpadSpacerTouchWithEmptyQuery() { + if (mInDialpadSearch && mSmartDialSearchFragment != null + && !mSmartDialSearchFragment.isShowingPermissionRequest()) { + hideDialpadFragment(true /* animate */, true /* clearDialpad */); + return true; + } + return false; } @Override diff --git a/src/com/android/dialer/calllog/CallLogFragment.java b/src/com/android/dialer/calllog/CallLogFragment.java index d1a9827eb..59e2c7f38 100644 --- a/src/com/android/dialer/calllog/CallLogFragment.java +++ b/src/com/android/dialer/calllog/CallLogFragment.java @@ -486,7 +486,7 @@ public class CallLogFragment extends Fragment implements CallLogQueryHandler.Lis } @Override - public void onEmptyViewActionButtonClicked(String[] permissions) { + public void onEmptyViewActionButtonClicked() { final Activity activity = getActivity(); if (activity == null) { return; diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java index b18069fdd..d35abd75b 100644 --- a/src/com/android/dialer/dialpad/DialpadFragment.java +++ b/src/com/android/dialer/dialpad/DialpadFragment.java @@ -135,6 +135,15 @@ public class DialpadFragment extends Fragment void onDialpadQueryChanged(String query); } + public interface HostInterface { + /** + * Notifies the parent activity that the space above the dialpad has been tapped with + * no query in the dialpad present. In most situations this will cause the dialpad to + * be dismissed, unless there happens to be content showing. + */ + boolean onDialpadSpacerTouchWithEmptyQuery(); + } + private static final boolean DEBUG = DialtactsActivity.DEBUG; // This is the amount of screen the dialpad fragment takes up when fully displayed @@ -385,7 +394,9 @@ public class DialpadFragment extends Fragment @Override public boolean onTouch(View v, MotionEvent event) { if (isDigitsEmpty()) { - hideAndClearDialpad(true); + if (getActivity() != null) { + return ((HostInterface) getActivity()).onDialpadSpacerTouchWithEmptyQuery(); + } return true; } return false; diff --git a/src/com/android/dialer/list/AllContactsFragment.java b/src/com/android/dialer/list/AllContactsFragment.java index 19d8a438a..0de84347e 100644 --- a/src/com/android/dialer/list/AllContactsFragment.java +++ b/src/com/android/dialer/list/AllContactsFragment.java @@ -133,7 +133,7 @@ public class AllContactsFragment extends ContactEntryListFragment<ContactEntryLi } @Override - public void onEmptyViewActionButtonClicked(String[] permissions) { + public void onEmptyViewActionButtonClicked() { final Activity activity = getActivity(); if (activity == null) { return; diff --git a/src/com/android/dialer/list/RegularSearchFragment.java b/src/com/android/dialer/list/RegularSearchFragment.java index 19c7321a1..b7e26d690 100644 --- a/src/com/android/dialer/list/RegularSearchFragment.java +++ b/src/com/android/dialer/list/RegularSearchFragment.java @@ -15,16 +15,29 @@ */ package com.android.dialer.list; +import static android.Manifest.permission.ACCESS_FINE_LOCATION; +import static android.Manifest.permission.READ_CONTACTS; + +import android.app.Activity; +import android.content.pm.PackageManager; import android.view.LayoutInflater; import android.view.ViewGroup; import com.android.contacts.common.list.ContactEntryListAdapter; import com.android.contacts.common.list.PinnedHeaderListView; +import com.android.contacts.common.util.PermissionsUtil; import com.android.contacts.commonbind.analytics.AnalyticsUtil; import com.android.dialerbind.ObjectFactory; + +import com.android.dialer.R; import com.android.dialer.service.CachedNumberLookupService; +import com.android.dialer.widget.EmptyContentView; +import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener; -public class RegularSearchFragment extends SearchFragment { +public class RegularSearchFragment extends SearchFragment + implements OnEmptyViewActionButtonClickedListener { + + private static final int READ_CONTACTS_PERMISSION_REQUEST_CODE = 1; private static final int SEARCH_DIRECTORY_RESULT_LIMIT = 5; @@ -68,4 +81,38 @@ public class RegularSearchFragment extends SearchFragment { adapter.getContactInfo(mCachedNumberLookupService, position)); } } + + @Override + protected void setupEmptyView() { + if (mEmptyView != null && getActivity() != null) { + if (!PermissionsUtil.hasPermission(getActivity(), READ_CONTACTS)) { + mEmptyView.setImage(R.drawable.empty_contacts); + mEmptyView.setActionLabel(R.string.permission_single_turn_on); + mEmptyView.setDescription(R.string.permission_no_search); + mEmptyView.setActionClickedListener(this); + } else { + mEmptyView.setImage(EmptyContentView.NO_IMAGE); + mEmptyView.setActionLabel(EmptyContentView.NO_LABEL); + mEmptyView.setDescription(EmptyContentView.NO_LABEL); + } + } + } + + @Override + public void onEmptyViewActionButtonClicked() { + final Activity activity = getActivity(); + if (activity == null) { + return; + } + + requestPermissions(new String[] {READ_CONTACTS}, READ_CONTACTS_PERMISSION_REQUEST_CODE); + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, + int[] grantResults) { + if (requestCode == READ_CONTACTS_PERMISSION_REQUEST_CODE) { + setupEmptyView(); + } + } } diff --git a/src/com/android/dialer/list/SearchFragment.java b/src/com/android/dialer/list/SearchFragment.java index 77ab29198..315cfb914 100644 --- a/src/com/android/dialer/list/SearchFragment.java +++ b/src/com/android/dialer/list/SearchFragment.java @@ -15,6 +15,8 @@ */ package com.android.dialer.list; +import static android.Manifest.permission.READ_CONTACTS; + import android.animation.Animator; import android.animation.AnimatorInflater; import android.animation.AnimatorListenerAdapter; @@ -50,6 +52,7 @@ import com.android.dialer.dialpad.DialpadFragment.ErrorDialogFragment; import com.android.dialer.R; import com.android.dialer.util.DialerUtils; import com.android.dialer.util.IntentUtil; +import com.android.dialer.widget.EmptyContentView; import com.android.phone.common.animation.AnimUtils; public class SearchFragment extends PhoneNumberPickerFragment { @@ -79,6 +82,8 @@ public class SearchFragment extends PhoneNumberPickerFragment { private HostInterface mActivity; + protected EmptyContentView mEmptyView; + public interface HostInterface { public boolean isActionBarShowing(); public boolean isDialpadShown(); @@ -125,6 +130,13 @@ public class SearchFragment extends PhoneNumberPickerFragment { final ListView listView = getListView(); + if (mEmptyView == null) { + mEmptyView = new EmptyContentView(getActivity()); + ((ViewGroup) getListView().getParent()).addView(mEmptyView); + getListView().setEmptyView(mEmptyView); + setupEmptyView(); + } + listView.setBackgroundColor(res.getColor(R.color.background_dialer_results)); listView.setClipToPadding(false); setVisibleScrollbarEnabled(false); @@ -341,7 +353,7 @@ public class SearchFragment extends PhoneNumberPickerFragment { @Override protected void startLoading() { - if (PermissionsUtil.hasContactsPermissions(getActivity())) { + if (PermissionsUtil.hasPermission(getActivity(), READ_CONTACTS)) { super.startLoading(); } else if (TextUtils.isEmpty(getQueryString())) { // Clear out any existing call shortcuts. @@ -354,6 +366,8 @@ public class SearchFragment extends PhoneNumberPickerFragment { // list. getAdapter().notifyDataSetChanged(); } + + setupEmptyView(); } public void setOnTouchListener(View.OnTouchListener onTouchListener) { @@ -371,4 +385,6 @@ public class SearchFragment extends PhoneNumberPickerFragment { } return parent; } + + protected void setupEmptyView() {} } diff --git a/src/com/android/dialer/list/SmartDialSearchFragment.java b/src/com/android/dialer/list/SmartDialSearchFragment.java index 082bc4360..72d3abf68 100644 --- a/src/com/android/dialer/list/SmartDialSearchFragment.java +++ b/src/com/android/dialer/list/SmartDialSearchFragment.java @@ -15,21 +15,33 @@ */ package com.android.dialer.list; +import static android.Manifest.permission.CALL_PHONE; + +import android.app.Activity; import android.content.Loader; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.util.Log; +import android.view.View; import com.android.contacts.common.list.ContactEntryListAdapter; +import com.android.contacts.common.util.PermissionsUtil; import com.android.dialer.dialpad.SmartDialCursorLoader; +import com.android.dialer.R; +import com.android.dialer.widget.EmptyContentView; + +import java.util.ArrayList; /** * Implements a fragment to load and display SmartDial search results. */ -public class SmartDialSearchFragment extends SearchFragment { +public class SmartDialSearchFragment extends SearchFragment + implements EmptyContentView.OnEmptyViewActionButtonClickedListener { private static final String TAG = SmartDialSearchFragment.class.getSimpleName(); + private static final int CALL_PHONE_PERMISSION_REQUEST_CODE = 1; + /** * Creates a SmartDialListAdapter to display and operate on search results. */ @@ -69,4 +81,42 @@ public class SmartDialSearchFragment extends SearchFragment { final SmartDialNumberListAdapter adapter = (SmartDialNumberListAdapter) getAdapter(); return adapter.getDataUri(position); } + + @Override + protected void setupEmptyView() { + if (mEmptyView != null && getActivity() != null) { + if (!PermissionsUtil.hasPermission(getActivity(), CALL_PHONE)) { + mEmptyView.setImage(R.drawable.empty_contacts); + mEmptyView.setActionLabel(R.string.permission_single_turn_on); + mEmptyView.setDescription(R.string.permission_place_call); + mEmptyView.setActionClickedListener(this); + } else { + mEmptyView.setImage(EmptyContentView.NO_IMAGE); + mEmptyView.setActionLabel(EmptyContentView.NO_LABEL); + mEmptyView.setDescription(EmptyContentView.NO_LABEL); + } + } + } + + @Override + public void onEmptyViewActionButtonClicked() { + final Activity activity = getActivity(); + if (activity == null) { + return; + } + + requestPermissions(new String[] {CALL_PHONE}, CALL_PHONE_PERMISSION_REQUEST_CODE); + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, + int[] grantResults) { + if (requestCode == CALL_PHONE_PERMISSION_REQUEST_CODE) { + setupEmptyView(); + } + } + + public boolean isShowingPermissionRequest() { + return mEmptyView != null && mEmptyView.isShowingContent(); + } } diff --git a/src/com/android/dialer/list/SpeedDialFragment.java b/src/com/android/dialer/list/SpeedDialFragment.java index aead1c81b..ebfc72da0 100644 --- a/src/com/android/dialer/list/SpeedDialFragment.java +++ b/src/com/android/dialer/list/SpeedDialFragment.java @@ -463,7 +463,7 @@ public class SpeedDialFragment extends Fragment implements OnItemClickListener, } @Override - public void onEmptyViewActionButtonClicked(String[] permissions) { + public void onEmptyViewActionButtonClicked() { final Activity activity = getActivity(); if (activity == null) { return; diff --git a/src/com/android/dialer/widget/EmptyContentView.java b/src/com/android/dialer/widget/EmptyContentView.java index 67c9ce15f..2f5e0d9d7 100644 --- a/src/com/android/dialer/widget/EmptyContentView.java +++ b/src/com/android/dialer/widget/EmptyContentView.java @@ -18,6 +18,7 @@ package com.android.dialer.widget; import android.content.Context; import android.util.AttributeSet; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; @@ -29,15 +30,15 @@ import com.android.dialer.R; public class EmptyContentView extends LinearLayout implements View.OnClickListener { public static final int NO_LABEL = 0; + public static final int NO_IMAGE = 0; private ImageView mImageView; private TextView mDescriptionView; private TextView mActionView; - private String[] mPermissions = new String[] {}; private OnEmptyViewActionButtonClickedListener mOnActionButtonClickedListener; public interface OnEmptyViewActionButtonClickedListener { - public void onEmptyViewActionButtonClicked(String[] permissions); + public void onEmptyViewActionButtonClicked(); } public EmptyContentView(Context context) { @@ -60,11 +61,6 @@ public class EmptyContentView extends LinearLayout implements View.OnClickListen final LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.empty_content_view, this); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); mImageView = (ImageView) findViewById(R.id.emptyListViewImage); mDescriptionView = (TextView) findViewById(R.id.emptyListViewMessage); mActionView = (TextView) findViewById(R.id.emptyListViewAction); @@ -72,11 +68,22 @@ public class EmptyContentView extends LinearLayout implements View.OnClickListen } public void setDescription(int resourceId) { - mDescriptionView.setText(resourceId); + if (resourceId == NO_LABEL) { + mDescriptionView.setText(null); + mDescriptionView.setVisibility(View.GONE); + } else { + mDescriptionView.setText(resourceId); + mDescriptionView.setVisibility(View.VISIBLE); + } } public void setImage(int resourceId) { mImageView.setImageResource(resourceId); + if (resourceId == NO_LABEL) { + mImageView.setVisibility(View.GONE); + } else { + mImageView.setVisibility(View.VISIBLE); + } } public void setActionLabel(int resourceId) { @@ -89,6 +96,12 @@ public class EmptyContentView extends LinearLayout implements View.OnClickListen } } + public boolean isShowingContent() { + return mImageView.getVisibility() == View.VISIBLE + || mDescriptionView.getVisibility() == View.VISIBLE + || mActionView.getVisibility() == View.VISIBLE; + } + public void setActionClickedListener(OnEmptyViewActionButtonClickedListener listener) { mOnActionButtonClickedListener = listener; } @@ -96,7 +109,7 @@ public class EmptyContentView extends LinearLayout implements View.OnClickListen @Override public void onClick(View v) { if (mOnActionButtonClickedListener != null) { - mOnActionButtonClickedListener.onEmptyViewActionButtonClicked(mPermissions); + mOnActionButtonClickedListener.onEmptyViewActionButtonClicked(); } } } |