am 7c5ca721: am 7e7e2bc0: am 7e03db72: am 91ecb136: Merge "Add permission prompts for contacts and dialpad search" into mnc-dev

* commit '7c5ca721664ff4c37a2e4cd754e8ac5283cde04d':
  Add permission prompts for contacts and dialpad search
diff --git a/res/layout/empty_content_view.xml b/res/layout/empty_content_view.xml
index d8f27aa..97ac4c7 100644
--- a/res/layout/empty_content_view.xml
+++ b/res/layout/empty_content_view.xml
@@ -43,7 +43,6 @@
         android:paddingLeft="16dp"
         android:paddingTop="8dp"
         android:paddingBottom="8dp"
-        android:text="@string/permission_single_turn_on"
         android:background="?android:attr/selectableItemBackground"
         android:clickable="true"
         style="@style/TextActionStyle" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 38b33bd..eec9b0c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -808,8 +808,8 @@
     <!-- Shown as a prompt to turn on the phone permission to show voicemails -->
     <string name="permission_no_voicemail">To access your voicemail,\n turn on the Phone permission.</string>
 
-    <!-- Shown as a prompt to turn on contacts and location permissions to allow contact and nearby places search -->
-    <string name="permission_no_search">To search your contacts and nearby locations, turn on the Contacts and Location permissions.</string>
+    <!-- Shown as a prompt to turn on contacts permissions to allow contact search -->
+    <string name="permission_no_search">To search your contacts, turn on the Contacts permissions.</string>
 
     <!-- Shown as a prompt to turn on the phone permission to allow a call to be placed -->
     <string name="permission_place_call">To place a call,\n turn on the Phone permission.</string>
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index 85197a5..98f34b5 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -103,6 +103,7 @@
         DialpadFragment.OnDialpadQueryChangedListener,
         OnListFragmentScrolledListener,
         CallLogFragment.HostInterface,
+        DialpadFragment.HostInterface,
         ListsFragment.HostInterface,
         SpeedDialFragment.HostInterface,
         SearchFragment.HostInterface,
@@ -486,8 +487,6 @@
                     }
                 });
 
-        setupActivityOverlay();
-
         Trace.endSection();
 
         Trace.beginSection(TAG + " initialize smart dialing");
@@ -497,19 +496,6 @@
         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 @@
         } 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 d1a9827..59e2c7f 100644
--- a/src/com/android/dialer/calllog/CallLogFragment.java
+++ b/src/com/android/dialer/calllog/CallLogFragment.java
@@ -486,7 +486,7 @@
     }
 
     @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 b18069f..d35abd7 100644
--- a/src/com/android/dialer/dialpad/DialpadFragment.java
+++ b/src/com/android/dialer/dialpad/DialpadFragment.java
@@ -135,6 +135,15 @@
         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 @@
             @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 19d8a43..0de8434 100644
--- a/src/com/android/dialer/list/AllContactsFragment.java
+++ b/src/com/android/dialer/list/AllContactsFragment.java
@@ -133,7 +133,7 @@
     }
 
     @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 19c7321..b7e26d6 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.service.CachedNumberLookupService;
 
-public class RegularSearchFragment extends SearchFragment {
+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
+        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 @@
                     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 77ab291..315cfb9 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.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 @@
 
     private HostInterface mActivity;
 
+    protected EmptyContentView mEmptyView;
+
     public interface HostInterface {
         public boolean isActionBarShowing();
         public boolean isDialpadShown();
@@ -125,6 +130,13 @@
 
         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 @@
 
     @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 @@
             // list.
             getAdapter().notifyDataSetChanged();
         }
+
+        setupEmptyView();
     }
 
     public void setOnTouchListener(View.OnTouchListener onTouchListener) {
@@ -371,4 +385,6 @@
         }
         return parent;
     }
+
+    protected void setupEmptyView() {}
 }
diff --git a/src/com/android/dialer/list/SmartDialSearchFragment.java b/src/com/android/dialer/list/SmartDialSearchFragment.java
index 082bc43..72d3abf 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 @@
         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 aead1c8..ebfc72d 100644
--- a/src/com/android/dialer/list/SpeedDialFragment.java
+++ b/src/com/android/dialer/list/SpeedDialFragment.java
@@ -463,7 +463,7 @@
     }
 
     @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 67c9ce1..2f5e0d9 100644
--- a/src/com/android/dialer/widget/EmptyContentView.java
+++ b/src/com/android/dialer/widget/EmptyContentView.java
@@ -18,6 +18,7 @@
 
 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 @@
 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 @@
         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 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 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 @@
     @Override
     public void onClick(View v) {
         if (mOnActionButtonClickedListener != null) {
-            mOnActionButtonClickedListener.onEmptyViewActionButtonClicked(mPermissions);
+            mOnActionButtonClickedListener.onEmptyViewActionButtonClicked();
         }
     }
 }