Merge "New editor flow (for master)"
diff --git a/res/drawable-hdpi/badge_action_call.png b/res/drawable-hdpi/badge_action_call.png
old mode 100755
new mode 100644
index 105f7d0..0b1c6b4
--- a/res/drawable-hdpi/badge_action_call.png
+++ b/res/drawable-hdpi/badge_action_call.png
Binary files differ
diff --git a/res/drawable-hdpi/badge_action_sms.png b/res/drawable-hdpi/badge_action_sms.png
old mode 100755
new mode 100644
index a7862f6..0dfdbf5
--- a/res/drawable-hdpi/badge_action_sms.png
+++ b/res/drawable-hdpi/badge_action_sms.png
Binary files differ
diff --git a/res/drawable-mdpi/badge_action_call.png b/res/drawable-mdpi/badge_action_call.png
index 3bc88a3..af2abaa 100644
--- a/res/drawable-mdpi/badge_action_call.png
+++ b/res/drawable-mdpi/badge_action_call.png
Binary files differ
diff --git a/res/drawable-mdpi/badge_action_sms.png b/res/drawable-mdpi/badge_action_sms.png
index bbcfb59..13dd8bc 100644
--- a/res/drawable-mdpi/badge_action_sms.png
+++ b/res/drawable-mdpi/badge_action_sms.png
Binary files differ
diff --git a/res/drawable-xhdpi/badge_action_call.png b/res/drawable-xhdpi/badge_action_call.png
index aa28018..2589e33 100644
--- a/res/drawable-xhdpi/badge_action_call.png
+++ b/res/drawable-xhdpi/badge_action_call.png
Binary files differ
diff --git a/res/drawable-xhdpi/badge_action_sms.png b/res/drawable-xhdpi/badge_action_sms.png
index 5e4cd82..460451f 100644
--- a/res/drawable-xhdpi/badge_action_sms.png
+++ b/res/drawable-xhdpi/badge_action_sms.png
Binary files differ
diff --git a/res/values/donottranslate_config.xml b/res/values/donottranslate_config.xml
index 0da6485..79a2b29 100644
--- a/res/values/donottranslate_config.xml
+++ b/res/values/donottranslate_config.xml
@@ -120,4 +120,8 @@
     <!-- Height of the tab carousel as a percentage of the current screen width on the
          contact detail page -->
     <item name="tab_height_screen_width_percentage" type="fraction">50%</item>
+
+    <!-- Regular expression for prohibiting certain phone numbers in dialpad.
+         Ignored if empty. -->
+    <string name="config_prohibited_phone_number_regexp"></string>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ed9dd0f..aa99d21 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1817,4 +1817,8 @@
 
     <!-- Button label to prompt the user to add another account (when there are already existing accounts on the device) [CHAR LIMIT=30] -->
     <string name="add_new_account">Add new account</string>
+
+    <!-- Dialog message which is shown when the user tries to make a phone call
+         to prohibited phone numbers [CHAR LIMIT=NONE] -->
+    <string name="phone_call_prohibited" msgid="4313552620858880999">Call not sent.</string>
 </resources>
diff --git a/src/com/android/contacts/dialpad/DialpadFragment.java b/src/com/android/contacts/dialpad/DialpadFragment.java
index 45cb03b..412ceff 100644
--- a/src/com/android/contacts/dialpad/DialpadFragment.java
+++ b/src/com/android/contacts/dialpad/DialpadFragment.java
@@ -27,8 +27,12 @@
 import com.android.phone.HapticFeedback;
 
 import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
 import android.app.Fragment;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.database.Cursor;
@@ -37,7 +41,6 @@
 import android.media.AudioManager;
 import android.media.ToneGenerator;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -46,7 +49,6 @@
 import android.provider.Contacts.Phones;
 import android.provider.Contacts.PhonesColumns;
 import android.provider.Settings;
-import android.telephony.PhoneNumberFormattingTextWatcher;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
@@ -61,16 +63,21 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
+import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.PopupMenu;
 import android.widget.TextView;
 
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * Fragment that displays a twelve-key phone dialpad.
  */
@@ -117,6 +124,11 @@
     private ListView mDialpadChooser;
     private DialpadChooserAdapter mDialpadChooserAdapter;
 
+    /**
+     * Regular expression prohibiting manual phone call. Can be empty, which means "no rule".
+     */
+    private String mProhibitedPhoneNumberRegexp;
+
     private boolean mShowOptionsMenu;
 
     private boolean mHasVoicemail = false;
@@ -219,6 +231,9 @@
         }
 
         setHasOptionsMenu(true);
+
+        mProhibitedPhoneNumberRegexp = getResources().getString(
+                R.string.config_prohibited_phone_number_regexp);
     }
 
     @Override
@@ -794,6 +809,26 @@
         getActivity().finish();
     }
 
+    public static class CallProhibitedDialogFragment extends DialogFragment {
+        public static CallProhibitedDialogFragment newInstance() {
+            return new CallProhibitedDialogFragment();
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            return new AlertDialog.Builder(getActivity())
+                    .setTitle(R.string.phone_call_prohibited)
+                    .setPositiveButton(android.R.string.ok,
+                            new DialogInterface.OnClickListener() {
+                                @Override
+                                public void onClick(DialogInterface dialog, int which) {
+                                    dismiss();
+                                }
+                            })
+                    .create();
+        }
+    }
+
     /**
      * In most cases, when the dial button is pressed, there is a
      * number in digits area. Pack it in the intent, start the
@@ -847,9 +882,22 @@
         } else {
             final String number = mDigits.getText().toString();
 
-            startActivity(newDialNumberIntent(number));
-            mDigits.getText().clear();  // TODO: Fix bug 1745781
-            getActivity().finish();
+            if (number != null
+                    && !TextUtils.isEmpty(mProhibitedPhoneNumberRegexp)
+                    && number.matches(mProhibitedPhoneNumberRegexp)) {
+                Log.i(TAG, "The phone number is prohibited explicitly by a rule.");
+                if (getActivity() != null) {
+                    DialogFragment dialogFragment = CallProhibitedDialogFragment.newInstance();
+                    dialogFragment.show(getFragmentManager(), "phone_prohibited_dialog");
+                }
+
+                // Clear the digits just in case.
+                mDigits.getText().clear();
+            } else {
+                startActivity(newDialNumberIntent(number));
+                mDigits.getText().clear();  // TODO: Fix bug 1745781
+                getActivity().finish();
+            }
         }
     }
 
@@ -1224,7 +1272,7 @@
                 // been entered, or if there is a last dialed number
                 // that could be redialed.
                 mDialButton.setEnabled(digitsNotEmpty ||
-                                       !TextUtils.isEmpty(mLastNumberDialed));
+                        !TextUtils.isEmpty(mLastNumberDialed));
             }
         }
         mDelete.setEnabled(digitsNotEmpty);
diff --git a/src/com/android/contacts/editor/ContactEditorUtils.java b/src/com/android/contacts/editor/ContactEditorUtils.java
index 900e68a..0e27223 100644
--- a/src/com/android/contacts/editor/ContactEditorUtils.java
+++ b/src/com/android/contacts/editor/ContactEditorUtils.java
@@ -65,7 +65,7 @@
 
     @VisibleForTesting
     ContactEditorUtils(Context context, AccountTypeManager accountTypes) {
-        mContext = context;
+        mContext = context.getApplicationContext();
         mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
         mAccountTypes = accountTypes;
     }
diff --git a/src/com/android/contacts/list/PhoneNumberPickerFragment.java b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
index 938d43a..015a364 100644
--- a/src/com/android/contacts/list/PhoneNumberPickerFragment.java
+++ b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
@@ -55,6 +55,9 @@
 
     private static final String KEY_FILTER = "filter";
 
+    /** true if the loader has started at least once. */
+    private boolean mLoaderStarted;
+
     // A complete copy from DefaultContactBrowserListFragment
     // TODO: should be able to share logic around filter header.
     private class FilterHeaderClickListener implements OnClickListener {
@@ -204,6 +207,12 @@
     }
 
     @Override
+    protected void startLoading() {
+        mLoaderStarted = true;
+        super.startLoading();
+    }
+
+    @Override
     protected ContactEntryListAdapter createListAdapter() {
         if (!isLegacyCompatibilityMode()) {
             PhoneNumberListAdapter adapter = new PhoneNumberListAdapter(getActivity());
@@ -272,7 +281,11 @@
             ContactListFilter.storeToPreferences(mPrefs, mFilter);
         }
 
-        reloadData();
+        // This method can be called before {@link #onStart} where we start the loader.  In that
+        // case we shouldn't start the loader yet, as we haven't done all initialization yet.
+        if (mLoaderStarted) {
+            reloadData();
+        }
         updateFilterHeaderView();
     }
 }