Merge "Fix merge"
diff --git a/src/com/android/dialer/compat/FilteredNumberCompat.java b/src/com/android/dialer/compat/FilteredNumberCompat.java
index 532cec5..91563dc 100644
--- a/src/com/android/dialer/compat/FilteredNumberCompat.java
+++ b/src/com/android/dialer/compat/FilteredNumberCompat.java
@@ -30,11 +30,14 @@
 import android.support.annotation.Nullable;
 import android.telecom.TelecomManager;
 import android.telephony.PhoneNumberUtils;
+import android.util.Log;
 
 import com.android.contacts.common.compat.CompatUtils;
 import com.android.contacts.common.compat.TelecomManagerUtil;
 import com.android.contacts.common.testing.NeededForTesting;
 import com.android.dialer.DialerApplication;
+import com.android.dialer.database.FilteredNumberAsyncQueryHandler;
+import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnCheckBlockedListener;
 import com.android.dialer.database.FilteredNumberContract.FilteredNumber;
 import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns;
 import com.android.dialer.database.FilteredNumberContract.FilteredNumberSources;
@@ -45,7 +48,6 @@
 import com.android.dialer.filterednumber.BlockedNumbersSettingsActivity;
 import com.android.dialer.filterednumber.MigrateBlockedNumbersDialogFragment;
 import com.android.dialerbind.ObjectFactory;
-import com.android.incallui.Log;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -257,18 +259,10 @@
         if (shouldShowMigrationDialog(blockId == null)) {
             Log.i(TAG, "showBlockNumberDialogFlow - showing migration dialog");
             MigrateBlockedNumbersDialogFragment
-                    .newInstance(new BlockedNumbersMigrator(contentResolver),
-                            new BlockedNumbersMigrator.Listener() {
-                                @Override
-                                public void onComplete() {
-                                    Log.i(TAG, "showBlockNumberDialogFlow - listener showing block "
-                                            + "number dialog");
-                                    BlockNumberDialogFragment
-                                            .show(null, number, countryIso, displayNumber,
-                                                    parentViewId,
-                                                    fragmentManager, callback);
-                                }
-                            }).show(fragmentManager, "MigrateBlockedNumbers");
+                    .newInstance(new BlockedNumbersMigrator(contentResolver), newMigrationListener(
+                            DialerApplication.getContext().getContentResolver(), number, countryIso,
+                            displayNumber, parentViewId, fragmentManager, callback))
+                    .show(fragmentManager, "MigrateBlockedNumbers");
             return;
         }
         Log.i(TAG, "showBlockNumberDialogFlow - showing block number dialog");
@@ -281,6 +275,43 @@
         return isBlocking && canUseNewFiltering() && !hasMigratedToNewBlocking();
     }
 
+    private static BlockedNumbersMigrator.Listener newMigrationListener(
+            final ContentResolver contentResolver, final String number, final String countryIso,
+            final String displayNumber, final Integer parentViewId,
+            final FragmentManager fragmentManager, @Nullable final Callback callback) {
+        return new BlockedNumbersMigrator.Listener() {
+            @Override
+            public void onComplete() {
+                Log.i(TAG, "showBlockNumberDialogFlow - listener showing block number dialog");
+                if (!hasMigratedToNewBlocking()) {
+                    Log.i(TAG, "showBlockNumberDialogFlow - migration failed");
+                    return;
+                }
+                /*
+                 * Edge case to cover here: if the user initiated the migration workflow with a
+                 * number that's already blocked in the framework, don't show the block number
+                 * dialog. Doing so would allow them to block the same number twice, causing a
+                 * crash.
+                 */
+                new FilteredNumberAsyncQueryHandler(contentResolver).isBlockedNumber(
+                        new OnCheckBlockedListener() {
+                            @Override
+                            public void onCheckComplete(Integer id) {
+                                if (id != null) {
+                                    Log.i(TAG,
+                                            "showBlockNumberDialogFlow - number already blocked");
+                                    return;
+                                }
+                                Log.i(TAG, "showBlockNumberDialogFlow - need to block number");
+                                BlockNumberDialogFragment
+                                        .show(null, number, countryIso, displayNumber, parentViewId,
+                                                fragmentManager, callback);
+                            }
+                        }, number, countryIso);
+            }
+        };
+    }
+
     /**
      * Creates the {@link Intent} which opens the blocked numbers management interface.
      *
diff --git a/tests/src/com/android/dialer/compat/FilteredNumberCompatInstrumentationTest.java b/tests/src/com/android/dialer/compat/FilteredNumberCompatInstrumentationTest.java
new file mode 100644
index 0000000..8ceb250
--- /dev/null
+++ b/tests/src/com/android/dialer/compat/FilteredNumberCompatInstrumentationTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.compat;
+
+import android.app.AlertDialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.DialogInterface;
+import android.provider.BlockedNumberContract.BlockedNumbers;
+import android.test.ActivityInstrumentationTestCase2;
+
+import com.android.contacts.common.compat.CompatUtils;
+import com.android.dialer.DialtactsActivity;
+import com.android.dialer.R;
+
+/**
+ * UI tests for FilteredNumberCompat
+ */
+public class FilteredNumberCompatInstrumentationTest extends
+        ActivityInstrumentationTestCase2<DialtactsActivity> {
+
+    private static final String E164_NUMBER = "+16502530000";
+    private static final String NUMBER = "6502530000";
+    private static final String COUNTRY_ISO = "US";
+
+    private ContentResolver mContentResolver;
+    private FragmentManager mFragmentManager;
+
+    public FilteredNumberCompatInstrumentationTest() {
+        super(DialtactsActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mContentResolver = getActivity().getContentResolver();
+        mFragmentManager = getActivity().getFragmentManager();
+        mContentResolver.delete(BlockedNumbersSdkCompat.CONTENT_URI,
+                BlockedNumbers.COLUMN_ORIGINAL_NUMBER + " = ?", new String[]{NUMBER});
+    }
+
+    public void testShowBlockNumberDialogFlow_AlreadyBlocked() throws InterruptedException {
+        if (!CompatUtils.isNCompatible()) {
+            return;
+        }
+
+        ContentValues values = new ContentValues();
+        values.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, NUMBER);
+        mContentResolver.insert(BlockedNumbers.CONTENT_URI, values);
+
+        FilteredNumberCompat.setHasMigratedToNewBlocking(false);
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                FilteredNumberCompat
+                        .showBlockNumberDialogFlow(mContentResolver, null, NUMBER, COUNTRY_ISO,
+                                E164_NUMBER, R.id.floating_action_button_container,
+                                mFragmentManager, null);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        final DialogFragment migrateDialogFragment = (DialogFragment) mFragmentManager
+                .findFragmentByTag("MigrateBlockedNumbers");
+        assertTrue(migrateDialogFragment.getDialog().isShowing());
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                ((AlertDialog) migrateDialogFragment.getDialog())
+                        .getButton(DialogInterface.BUTTON_POSITIVE).performClick();
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+        assertNull(mFragmentManager.findFragmentByTag("BlockNumberDialog"));
+    }
+}