Merge "Notify for call blocking disabled by E911." into ub-contactsdialer-a-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b5703c6..f74d2ea 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -883,12 +883,6 @@
     <!-- Heading for the block list in the "Spam and blocked cal)ls" settings. [CHAR LIMIT=64] -->
     <string name="blockList">Block list</string>
 
-    <!-- Label for progress dialog when validating a number to be added to the block list.
-        [CHAR LIMIT=64] -->
-    <string name="checkingNumber">Checking
-        <xliff:g id="number" example="(555) 555-5555">%1$s</xliff:g>
-    </string>
-
     <!-- Error message shown when user tries to add invalid number to the block list.
         [CHAR LIMIT=64] -->
     <string name="invalidNumber"><xliff:g id="number" example="(555) 555-5555">%1$s</xliff:g>
@@ -899,6 +893,19 @@
     <string name="alreadyBlocked"><xliff:g id="number" example="(555) 555-5555">%1$s</xliff:g>
         is already blocked.</string>
 
+    <!-- Title of notification telling the user that call blocking has been temporarily disabled.
+         [CHAR LIMIT=56] -->
+    <string name="call_blocking_disabled_notification_title">
+        Call blocking disabled for 48 hours
+    </string>
+
+    <!-- Text for notification which provides the reason that call blocking has been temporarily
+         disabled. Namely, we disable call blocking after an emergency call in case of return
+         phone calls made by emergency services. [CHAR LIMIT=64] -->
+    <string name="call_blocking_disabled_notification_text">
+        Disabled because an emergency call was made.
+    </string>
+
     <!-- Label for the phone account settings [CHAR LIMIT=30] -->
     <string name="phone_account_settings_label">Calling accounts</string>
 
diff --git a/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java b/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java
index 25613a6..e875f12 100644
--- a/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java
+++ b/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java
@@ -78,6 +78,14 @@
         public void onUnblockComplete(int rows, ContentValues values);
     }
 
+    public interface OnHasBlockedNumbersListener {
+        /**
+         * @param hasBlockedNumbers {@code true} if any blocked numbers are stored.
+         *     {@code false} otherwise.
+         */
+        public void onHasBlockedNumbers(boolean hasBlockedNumbers);
+    }
+
     @Override
     protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
         if (cookie != null) {
@@ -120,6 +128,21 @@
                 null, null, null);
     }
 
+    public final void hasBlockedNumbersAsync(final OnHasBlockedNumbersListener listener) {
+        startQuery(NO_TOKEN,
+                new Listener() {
+                    @Override
+                    protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+                        listener.onHasBlockedNumbers(cursor.getCount() > 0);
+                    }
+                },
+                getContentUri(null),
+                new String[]{ FilteredNumberColumns._ID },
+                FilteredNumberColumns.TYPE + "=" + FilteredNumberTypes.BLOCKED_NUMBER,
+                null,
+                null);
+    }
+
     /**
      * Check if the number + country iso given has been blocked.
      * This method normalizes the number for the lookup if normalizedNumber is null.
diff --git a/src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java b/src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java
index 8473e32..4b4af4d 100644
--- a/src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java
+++ b/src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java
@@ -21,6 +21,7 @@
 import android.app.DialogFragment;
 import android.app.FragmentManager;
 import android.content.ContentValues;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.content.res.Resources;
 import android.net.Uri;
@@ -187,6 +188,7 @@
         final String undoMessage = getUnblockedMessage();
         final Callback callback = mCallback;
         final int actionTextColor = getActionTextColor();
+        final Context context = getContext();
 
         final OnUnblockNumberListener onUndoListener = new OnUnblockNumberListener() {
             @Override
@@ -217,6 +219,10 @@
                 if (callback != null) {
                     callback.onChangeFilteredNumberSuccess();
                 }
+
+                if (context != null && FilteredNumbersUtil.hasRecentEmergencyCall(context)) {
+                    FilteredNumbersUtil.maybeNotifyCallBlockingDisabled(context);
+                }
             }
         };
 
diff --git a/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java b/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java
index 854a5bb..4492c51 100644
--- a/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java
+++ b/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java
@@ -15,8 +15,12 @@
  */
 package com.android.dialer.filterednumber;
 
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.Intent;
 import android.database.Cursor;
 import android.os.AsyncTask;
 import android.preference.PreferenceManager;
@@ -36,6 +40,7 @@
 import com.android.contacts.common.util.PhoneNumberHelper;
 import com.android.dialer.R;
 import com.android.dialer.database.FilteredNumberAsyncQueryHandler;
+import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnHasBlockedNumbersListener;
 import com.android.dialer.database.FilteredNumberContract.FilteredNumber;
 import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns;
 
@@ -44,13 +49,21 @@
  */
 public class FilteredNumbersUtil {
 
-    private static final String HIDE_BLOCKED_CALLS_PREF_KEY = "hide_blocked_calls";
-    // Pref key for storing the time, in milliseconds after epoch, of end of the last emergency call.
-    private static final String LAST_EMERGENCY_CALL_PREF_KEY = "last_emergency_call";
-
     // Disable incoming call blocking if there was a call within the past 2 days.
     private static final long RECENT_EMERGENCY_CALL_THRESHOLD_MS = 1000 * 60 * 60 * 24 * 2;
 
+    private static final String HIDE_BLOCKED_CALLS_PREF_KEY = "hide_blocked_calls";
+    // Pref key for storing the time of end of the last emergency call in milliseconds after epoch.
+    private static final String LAST_EMERGENCY_CALL_MS_PREF_KEY = "last_emergency_call_ms";
+
+    // Pref key for storing whether a notification has been dispatched to notify the user that call
+    // blocking has been disabled because of a recent emergency call.
+    private static final String NOTIFIED_CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_PREF_KEY =
+            "notified_call_blocking_disabled_by_emergency_call";
+
+    public static final String CALL_BLOCKING_NOTIFICATION_TAG = "call_blocking";
+    public static final int CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_NOTIFICATION_ID = 10;
+
     /**
      * Used for testing to specify that a custom threshold should be used instead of the default.
      * This custom threshold will only be used when setting this log tag to VERBOSE:
@@ -257,7 +270,7 @@
             return false;
         }
         return PreferenceManager.getDefaultSharedPreferences(context)
-                .getBoolean(FilteredNumbersUtil.HIDE_BLOCKED_CALLS_PREF_KEY, false);
+                .getBoolean(HIDE_BLOCKED_CALLS_PREF_KEY, false);
     }
 
     public static void setShouldHideBlockedCalls(Context context, boolean shouldHide) {
@@ -276,7 +289,7 @@
         }
 
         Long lastEmergencyCallTime = PreferenceManager.getDefaultSharedPreferences(context)
-                .getLong(LAST_EMERGENCY_CALL_PREF_KEY, 0);
+                .getLong(LAST_EMERGENCY_CALL_MS_PREF_KEY, 0);
         if (lastEmergencyCallTime == 0) {
             return false;
         }
@@ -289,10 +302,59 @@
         if (context == null) {
             return;
         }
+
         PreferenceManager.getDefaultSharedPreferences(context)
                 .edit()
-                .putLong(LAST_EMERGENCY_CALL_PREF_KEY, System.currentTimeMillis())
+                .putLong(LAST_EMERGENCY_CALL_MS_PREF_KEY, System.currentTimeMillis())
+                .putBoolean(NOTIFIED_CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_PREF_KEY, false)
                 .apply();
+
+        maybeNotifyCallBlockingDisabled(context);
+    }
+
+    public static void maybeNotifyCallBlockingDisabled(final Context context) {
+        // Skip if the user has already received a notification for the most recent emergency call.
+        if (PreferenceManager.getDefaultSharedPreferences(context)
+                .getBoolean(NOTIFIED_CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_PREF_KEY, false)) {
+            return;
+        }
+
+        // If the user has blocked numbers, notify that call blocking is temporarily disabled.
+        FilteredNumberAsyncQueryHandler queryHandler =
+                new FilteredNumberAsyncQueryHandler(context.getContentResolver());
+        queryHandler.hasBlockedNumbersAsync(new OnHasBlockedNumbersListener() {
+            @Override
+            public void onHasBlockedNumbers(boolean hasBlockedNumbers) {
+                if (context == null || !hasBlockedNumbers) {
+                    return;
+                }
+
+                NotificationManager notificationManager = (NotificationManager)
+                        context.getSystemService(Context.NOTIFICATION_SERVICE);
+                Notification.Builder builder = new Notification.Builder(context)
+                        .setSmallIcon(R.drawable.ic_block_24dp)
+                        .setContentTitle(context.getString(
+                                R.string.call_blocking_disabled_notification_title))
+                        .setContentText(context.getString(
+                                R.string.call_blocking_disabled_notification_text));
+
+                final Intent contentIntent =
+                        new Intent(context, ManageBlockedNumbersActivity.class);
+                builder.setContentIntent(PendingIntent.getActivity(
+                        context, 0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT));
+
+                notificationManager.notify(
+                        CALL_BLOCKING_NOTIFICATION_TAG,
+                        CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_NOTIFICATION_ID,
+                        builder.build());
+
+                // Record that the user has been notified for this emergency call.
+                PreferenceManager.getDefaultSharedPreferences(context)
+                    .edit()
+                    .putBoolean(NOTIFIED_CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_PREF_KEY, true)
+                    .apply();
+            }
+        });
     }
 
     public static boolean canBlockNumber(Context context, String number) {