summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/values/ids.xml1
-rw-r--r--res/values/strings.xml32
-rw-r--r--src/com/android/dialer/calllog/CallLogAdapter.java104
-rw-r--r--src/com/android/dialer/calllog/CallLogListItemHelper.java3
-rw-r--r--src/com/android/dialer/calllog/CallLogListItemViewHolder.java118
-rw-r--r--src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java95
-rw-r--r--src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java154
7 files changed, 376 insertions, 131 deletions
diff --git a/res/values/ids.xml b/res/values/ids.xml
index cb2025aa9..0034fe3d4 100644
--- a/res/values/ids.xml
+++ b/res/values/ids.xml
@@ -18,5 +18,6 @@
<item type="id" name="context_menu_copy_to_clipboard" />
<item type="id" name="context_menu_copy_transcript_to_clipboard" />
<item type="id" name="context_menu_edit_before_call" />
+ <item type="id" name="context_menu_block_number" />
<item type="id" name="settings_header_sounds_and_vibration" />
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1ce6ab65c..7bd88baef 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -52,6 +52,24 @@
<!-- Option displayed in context menu to copy long pressed voicemail transcription to clipboard [CHAR LIMIT=64] -->
<string name="copy_transcript_text">Copy transcription to clipboard</string>
+ <!-- Menu item used to block a number from the call log [CHAR LIMIT=64] -->
+ <string name="call_log_block_number">Block number</string>
+
+ <!-- Text for snackbar to undo blocking a number. [CHAR LIMIT=64] -->
+ <string name="snackbar_number_blocked">
+ <xliff:g id="number" example="(555) 555-5555">%1$s</xliff:g> added to block list</string>
+
+ <!-- Menu item used to unblock a number from the call log [CHAR LIMIT=64]-->
+ <string name="call_log_unblock_number">Unblock number</string>
+
+ <!-- Text for snackbar to undo unblocking a number. [CHAR LIMIT=64] -->
+ <string name="snackbar_number_unblocked">
+ <xliff:g id="number" example="(555) 555-5555">%1$s</xliff:g>
+ removed from block list</string>
+
+ <!-- Text for undo button in snackbar for blocking/unblocking number. [CHAR LIMIT=10] -->
+ <string name="block_number_undo">UNDO</string>
+
<!-- Menu item used to copy a number from the call log to the dialer so it can be edited before calling it -->
<string name="call_log_edit_number_before_call">Edit number before call</string>
@@ -490,6 +508,20 @@
[CHAR LIMIT=30] -->
<string name="call_log_voicemail_title">Voicemail</string>
+ <!-- Confirmation dialog for blocking a number. [CHAR LIMIT=NONE] -->
+ <string name="blockNumberConfirmation">Add
+ <xliff:g id="number" example="(555) 555-5555">%1$s</xliff:g> to your block list?</string>
+
+ <!-- Block number alert dialog button [CHAR LIMIT=32] -->
+ <string name="blockNumberOk">Block number</string>
+
+ <!-- Confirmation dialog for unblocking a number. [CHAR LIMIT=NONE] -->
+ <string name="unblockNumberConfirmation">Remove
+ <xliff:g id="number" example="(555) 555-5555">%1$s</xliff:g> from your block list?</string>
+
+ <!-- Unblock number alert dialog button [CHAR LIMIT=32] -->
+ <string name="unblockNumberOk">Unblock number</string>
+
<!-- Accessibility text for the tab showing recent and favorite contacts who can be called.
[CHAR LIMIT=40] -->
<string name="tab_speed_dial">Speed dial</string>
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 4593e5e4d..4d4d454d0 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -22,12 +22,10 @@ import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
-import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.support.v7.widget.RecyclerView;
import android.os.Bundle;
import android.os.Trace;
-import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.provider.CallLog;
import android.support.v7.widget.RecyclerView.ViewHolder;
@@ -35,28 +33,18 @@ import android.telecom.PhoneAccountHandle;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
-import android.util.Log;
-import android.view.ContextMenu;
import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.view.View.AccessibilityDelegate;
import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.view.ContextMenu.ContextMenuInfo;
import android.view.accessibility.AccessibilityEvent;
-import android.widget.TextView;
-import com.android.contacts.common.CallUtil;
-import com.android.contacts.common.ClipboardUtils;
import com.android.contacts.common.util.PermissionsUtil;
-import com.android.dialer.DialtactsActivity;
import com.android.dialer.PhoneCallDetails;
import com.android.dialer.R;
import com.android.dialer.contactinfo.ContactInfoCache;
import com.android.dialer.contactinfo.ContactInfoCache.OnContactInfoChangedListener;
-import com.android.dialer.util.DialerUtils;
+import com.android.dialer.database.FilteredNumberAsyncQueryHandler;
import com.android.dialer.util.PhoneNumberUtil;
import com.android.dialer.voicemail.VoicemailPlaybackPresenter;
@@ -96,6 +84,7 @@ public class CallLogAdapter extends GroupingListAdapter
private final ContactInfoHelper mContactInfoHelper;
protected final VoicemailPlaybackPresenter mVoicemailPlaybackPresenter;
private final CallFetcher mCallFetcher;
+ private final FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler;
protected ContactInfoCache mContactInfoCache;
@@ -195,89 +184,6 @@ public class CallLogAdapter extends GroupingListAdapter
}
};
- /**
- * Listener that is triggered to populate the context menu with actions to perform on the call's
- * number, when the call log entry is long pressed.
- */
- private final View.OnCreateContextMenuListener mOnCreateContextMenuListener =
- new View.OnCreateContextMenuListener() {
- @Override
- public void onCreateContextMenu(
- ContextMenu menu, View v, ContextMenuInfo menuInfo) {
- final CallLogListItemViewHolder vh = (CallLogListItemViewHolder) v.getTag();
- if (TextUtils.isEmpty(vh.number)) {
- return;
- }
-
- if (vh.callType == CallLog.Calls.VOICEMAIL_TYPE) {
- menu.setHeaderTitle(mContext.getResources().getText(R.string.voicemail));
- } else {
- menu.setHeaderTitle(vh.number);
- }
-
- final MenuItem copyItem = menu.add(
- ContextMenu.NONE,
- R.id.context_menu_copy_to_clipboard,
- ContextMenu.NONE,
- R.string.copy_number_text);
-
- copyItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- ClipboardUtils.copyText(mContext, null, vh.number, true);
- return true;
- }
- });
-
- // The edit number before call does not show up if any of the conditions apply:
- // 1) Number cannot be called
- // 2) Number is the voicemail number
- // 3) Number is a SIP address
-
- if (PhoneNumberUtil.canPlaceCallsTo(vh.number, vh.numberPresentation)
- && !mTelecomCallLogCache.isVoicemailNumber(vh.accountHandle, vh.number)
- && !PhoneNumberUtil.isSipNumber(vh.number)) {
- final MenuItem editItem = menu.add(
- ContextMenu.NONE,
- R.id.context_menu_edit_before_call,
- ContextMenu.NONE,
- R.string.call_log_edit_number_before_call);
-
- editItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- final Intent intent = new Intent(
- Intent.ACTION_DIAL, CallUtil.getCallUri(vh.number));
- intent.setClass(mContext, DialtactsActivity.class);
- DialerUtils.startActivityWithErrorToast(mContext, intent);
- return true;
- }
- });
- }
-
- final TextView transcriptView =
- vh.phoneCallDetailsViews.voicemailTranscriptionView;
- if (vh.callType == CallLog.Calls.VOICEMAIL_TYPE
- && transcriptView.length() > 0) {
- final MenuItem copyTranscriptItem = menu.add(
- ContextMenu.NONE,
- R.id.context_menu_copy_transcript_to_clipboard,
- ContextMenu.NONE,
- R.string.copy_transcript_text);
-
- copyTranscriptItem.setOnMenuItemClickListener(
- new OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- ClipboardUtils.copyText(
- mContext, null, transcriptView.getText(), true);
- return true;
- }
- });
- }
- }
- };
-
private void expandViewHolderActions(CallLogListItemViewHolder viewHolder) {
// If another item is expanded, notify it that it has changed. Its actions will be
// hidden when it is re-binded because we change mCurrentlyExpandedPosition below.
@@ -351,6 +257,8 @@ public class CallLogAdapter extends GroupingListAdapter
mCallLogGroupBuilder = new CallLogGroupBuilder(this);
mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
maybeShowVoicemailPromoCard();
+ mFilteredNumberAsyncQueryHandler =
+ new FilteredNumberAsyncQueryHandler(mContext.getContentResolver());
}
public void onSaveInstanceState(Bundle outState) {
@@ -439,12 +347,12 @@ public class CallLogAdapter extends GroupingListAdapter
mExpandCollapseListener,
mTelecomCallLogCache,
mCallLogListItemHelper,
- mVoicemailPlaybackPresenter);
+ mVoicemailPlaybackPresenter,
+ mFilteredNumberAsyncQueryHandler);
viewHolder.callLogEntryView.setTag(viewHolder);
viewHolder.callLogEntryView.setAccessibilityDelegate(mAccessibilityDelegate);
- viewHolder.primaryActionView.setOnCreateContextMenuListener(mOnCreateContextMenuListener);
viewHolder.primaryActionView.setTag(viewHolder);
return viewHolder;
diff --git a/src/com/android/dialer/calllog/CallLogListItemHelper.java b/src/com/android/dialer/calllog/CallLogListItemHelper.java
index 1c8e397e4..d18e274ba 100644
--- a/src/com/android/dialer/calllog/CallLogListItemHelper.java
+++ b/src/com/android/dialer/calllog/CallLogListItemHelper.java
@@ -74,6 +74,9 @@ import com.android.dialer.R;
// Cache name or number of caller. Used when setting the content descriptions of buttons
// when the actions ViewStub is inflated.
views.nameOrNumber = getNameOrNumber(details);
+
+ // Cache country iso. Used for number filtering.
+ views.countryIso = details.countryIso;
}
/**
diff --git a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
index d85deb36f..521b2a429 100644
--- a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
+++ b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
@@ -21,12 +21,15 @@ import android.content.Context;
import android.content.res.Resources;
import android.content.Intent;
import android.net.Uri;
+import android.provider.CallLog;
import android.provider.CallLog.Calls;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.telecom.PhoneAccountHandle;
import android.text.TextUtils;
+import android.view.ContextMenu;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
@@ -34,12 +37,17 @@ import android.widget.QuickContactBadge;
import android.widget.ImageView;
import android.widget.TextView;
+import com.android.contacts.common.CallUtil;
+import com.android.contacts.common.ClipboardUtils;
import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
import com.android.contacts.common.dialog.CallSubjectDialog;
import com.android.contacts.common.testing.NeededForTesting;
import com.android.contacts.common.util.UriUtils;
+import com.android.dialer.DialtactsActivity;
import com.android.dialer.R;
+import com.android.dialer.database.FilteredNumberAsyncQueryHandler;
+import com.android.dialer.filterednumber.FilterNumberDialogFragment;
import com.android.dialer.util.DialerUtils;
import com.android.dialer.util.PhoneNumberUtil;
import com.android.dialer.voicemail.VoicemailPlaybackPresenter;
@@ -52,7 +60,8 @@ import com.android.dialer.voicemail.VoicemailPlaybackLayout;
* This object also contains UI logic pertaining to the view, to isolate it from the CallLogAdapter.
*/
public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
- implements View.OnClickListener {
+ implements View.OnClickListener, MenuItem.OnMenuItemClickListener,
+ View.OnCreateContextMenuListener {
/** The root view of the call log list item */
public final View rootView;
@@ -116,12 +125,24 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
public String numberType;
/**
+ * The country iso for the call. Cached here as the call back
+ * intent is set only when the actions ViewStub is inflated.
+ */
+ public String countryIso;
+
+ /**
* The type of call for the current call log entry. Cached here as the call back
* intent is set only when the actions ViewStub is inflated.
*/
public int callType;
/**
+ * ID for blocked numbers database.
+ * Set when context menu is created, if the number is blocked.
+ */
+ public Integer blockId;
+
+ /**
* The account for the current call log entry. Cached here as the call back
* intent is set only when the actions ViewStub is inflated.
*/
@@ -156,6 +177,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
private final TelecomCallLogCache mTelecomCallLogCache;
private final CallLogListItemHelper mCallLogListItemHelper;
private final VoicemailPlaybackPresenter mVoicemailPlaybackPresenter;
+ private final FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler;
private final int mPhotoSize;
@@ -168,6 +190,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
TelecomCallLogCache telecomCallLogCache,
CallLogListItemHelper callLogListItemHelper,
VoicemailPlaybackPresenter voicemailPlaybackPresenter,
+ FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler,
View rootView,
QuickContactBadge quickContactView,
View primaryActionView,
@@ -182,6 +205,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
mTelecomCallLogCache = telecomCallLogCache;
mCallLogListItemHelper = callLogListItemHelper;
mVoicemailPlaybackPresenter = voicemailPlaybackPresenter;
+ mFilteredNumberAsyncQueryHandler = filteredNumberAsyncQueryHandler;
this.rootView = rootView;
this.quickContactView = quickContactView;
@@ -202,6 +226,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
primaryActionButtonView.setOnClickListener(this);
primaryActionView.setOnClickListener(mExpandCollapseListener);
+ primaryActionView.setOnCreateContextMenuListener(this);
}
public static CallLogListItemViewHolder create(
@@ -210,7 +235,8 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
View.OnClickListener expandCollapseListener,
TelecomCallLogCache telecomCallLogCache,
CallLogListItemHelper callLogListItemHelper,
- VoicemailPlaybackPresenter voicemailPlaybackPresenter) {
+ VoicemailPlaybackPresenter voicemailPlaybackPresenter,
+ FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler) {
return new CallLogListItemViewHolder(
context,
@@ -218,6 +244,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
telecomCallLogCache,
callLogListItemHelper,
voicemailPlaybackPresenter,
+ filteredNumberAsyncQueryHandler,
view,
(QuickContactBadge) view.findViewById(R.id.quick_contact_photo),
view.findViewById(R.id.primary_action_view),
@@ -227,6 +254,92 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
(ImageView) view.findViewById(R.id.primary_action_button));
}
+ @Override
+ public void onCreateContextMenu(
+ final ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ if (TextUtils.isEmpty(number)) {
+ return;
+ }
+
+ if (callType == CallLog.Calls.VOICEMAIL_TYPE) {
+ menu.setHeaderTitle(mContext.getResources().getText(R.string.voicemail));
+ } else {
+ menu.setHeaderTitle(number);
+ }
+
+ menu.add(ContextMenu.NONE, R.id.context_menu_copy_to_clipboard, ContextMenu.NONE,
+ R.string.copy_number_text)
+ .setOnMenuItemClickListener(this);
+
+ // The edit number before call does not show up if any of the conditions apply:
+ // 1) Number cannot be called
+ // 2) Number is the voicemail number
+ // 3) Number is a SIP address
+
+ if (PhoneNumberUtil.canPlaceCallsTo(number, numberPresentation)
+ && !mTelecomCallLogCache.isVoicemailNumber(accountHandle, number)
+ && !PhoneNumberUtil.isSipNumber(number)) {
+ menu.add(ContextMenu.NONE, R.id.context_menu_edit_before_call, ContextMenu.NONE,
+ R.string.call_log_edit_number_before_call)
+ .setOnMenuItemClickListener(this);
+ }
+
+ if (callType == CallLog.Calls.VOICEMAIL_TYPE
+ && phoneCallDetailsViews.voicemailTranscriptionView.length() > 0) {
+ menu.add(ContextMenu.NONE, R.id.context_menu_copy_transcript_to_clipboard,
+ ContextMenu.NONE, R.string.copy_transcript_text)
+ .setOnMenuItemClickListener(this);
+ }
+
+ try {
+ mFilteredNumberAsyncQueryHandler.isBlocked(
+ new FilteredNumberAsyncQueryHandler.OnCheckBlockedListener() {
+ @Override
+ public void onCheckComplete(Integer id) {
+ blockId = id;
+ int blockTitleId = blockId == null ? R.string.call_log_block_number
+ : R.string.call_log_unblock_number;
+ final MenuItem blockItem = menu.add(
+ ContextMenu.NONE,
+ R.id.context_menu_block_number,
+ ContextMenu.NONE,
+ blockTitleId);
+ blockItem.setOnMenuItemClickListener(
+ CallLogListItemViewHolder.this);
+ }
+ }, info.normalizedNumber, number, countryIso);
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.context_menu_block_number:
+ FilterNumberDialogFragment newFragment =
+ FilterNumberDialogFragment.newInstance(blockId, info.normalizedNumber,
+ number, countryIso, info.formattedNumber);
+ newFragment.setQueryHandler(mFilteredNumberAsyncQueryHandler);
+ newFragment.show(((Activity) mContext).getFragmentManager(),
+ FilterNumberDialogFragment.BLOCK_DIALOG_FRAGMENT);
+ return true;
+ case R.id.context_menu_copy_to_clipboard:
+ ClipboardUtils.copyText(mContext, null, number, true);
+ return true;
+ case R.id.context_menu_copy_transcript_to_clipboard:
+ ClipboardUtils.copyText(mContext, null,
+ phoneCallDetailsViews.voicemailTranscriptionView.getText(), true);
+ return true;
+ case R.id.context_menu_edit_before_call:
+ final Intent intent = new Intent(
+ Intent.ACTION_DIAL, CallUtil.getCallUri(number));
+ intent.setClass(mContext, DialtactsActivity.class);
+ DialerUtils.startActivityWithErrorToast(mContext, intent);
+ return true;
+ }
+ return false;
+ }
+
/**
* Configures the action buttons in the expandable actions ViewStub. The ViewStub is not
* inflated during initial binding, so click handlers, tags and accessibility text must be set
@@ -488,6 +601,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
telecomCallLogCache,
new CallLogListItemHelper(phoneCallDetailsHelper, resources, telecomCallLogCache),
null /* voicemailPlaybackPresenter */,
+ null /* filteredNumberAsyncQueryHandler */,
new View(context),
new QuickContactBadge(context),
new View(context),
diff --git a/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java b/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java
index 58a717b8b..2fdea0d13 100644
--- a/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java
+++ b/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java
@@ -21,6 +21,8 @@ import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabaseCorruptException;
import android.net.Uri;
import android.telephony.PhoneNumberUtils;
@@ -51,15 +53,28 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler {
}
public interface OnCheckBlockedListener {
- public void onQueryComplete(Integer id);
+ /**
+ * Invoked after querying if a number is blocked.
+ * @param id The ID of the row if blocked, null otherwise.
+ */
+ public void onCheckComplete(Integer id);
}
public interface OnBlockNumberListener {
- public void onInsertComplete(Uri uri);
+ /**
+ * Invoked after inserting a blocked number.
+ * @param uri The uri of the newly created row.
+ */
+ public void onBlockComplete(Uri uri);
}
public interface OnUnblockNumberListener {
- public void onDeleteComplete(int rows);
+ /**
+ * Invoked after removing a blocked number
+ * @param rows The number of rows affected (expected value 1).
+ * @param values The deleted data (used for restoration).
+ */
+ public void onUnblockComplete(int rows, ContentValues values);
}
@Override
@@ -93,7 +108,6 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler {
/**
* Check if the number + country iso given has been blocked.
* This method normalizes the number for the lookup if normalizedNumber is null.
- * Returns to the listener the the ID of the row if blocked, null otherwise.
*/
public final void isBlocked(final OnCheckBlockedListener listener,
String normalizedNumber, String number, String countryIso) {
@@ -108,25 +122,24 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler {
/**
* Check if the normalized number given has been blocked.
- * Returns to the listener the ID of the row if blocked, null otherwise.
*/
public final void isBlocked(final OnCheckBlockedListener listener,
- String normalizedNumber) {
+ String normalizedNumber) {
startQuery(NO_TOKEN,
new Listener() {
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
if (cursor.getCount() != 1) {
- listener.onQueryComplete(null);
+ listener.onCheckComplete(null);
return;
}
cursor.moveToFirst();
if (cursor.getInt(cursor.getColumnIndex(FilteredNumberColumns.TYPE))
!= FilteredNumberTypes.BLOCKED_NUMBER) {
- listener.onQueryComplete(null);
+ listener.onCheckComplete(null);
return;
}
- listener.onQueryComplete(
+ listener.onCheckComplete(
cursor.getInt(cursor.getColumnIndex(FilteredNumberColumns._ID)));
}
},
@@ -139,22 +152,11 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler {
/**
* Add a number manually blocked by the user.
- * Returns to the listener the URL of the newly created row.
*/
public final void blockNumber(final OnBlockNumberListener listener,
- String number, String countryIso) {
- blockNumber(listener,
- PhoneNumberUtils.formatNumberToE164(number, countryIso), number, countryIso);
- }
-
- /**
- * Add a number manually blocked by the user.
- * Returns to the listener the URL of the newly created row.
- */
- public final void blockNumber(final OnBlockNumberListener listener,
- String normalizedNumber, String number, String countryIso) {
+ String normalizedNumber, String number, String countryIso) {
if (normalizedNumber == null) {
- blockNumber(listener, number, countryIso);
+ normalizedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso);
}
ContentValues v = new ContentValues();
v.put(FilteredNumberColumns.NORMALIZED_NUMBER, normalizedNumber);
@@ -162,30 +164,61 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler {
v.put(FilteredNumberColumns.COUNTRY_ISO, countryIso);
v.put(FilteredNumberColumns.TYPE, FilteredNumberTypes.BLOCKED_NUMBER);
v.put(FilteredNumberColumns.SOURCE, FilteredNumberSources.USER);
+ blockNumber(listener, v);
+ }
+
+ /**
+ * Block a number with specified ContentValues. Can be manually added or a restored row
+ * from performing the 'undo' action after unblocking.
+ */
+ public final void blockNumber(final OnBlockNumberListener listener, ContentValues values) {
startInsert(NO_TOKEN,
new Listener() {
@Override
public void onInsertComplete(int token, Object cookie, Uri uri) {
- listener.onInsertComplete(uri);
+ listener.onBlockComplete(uri);
}
- }, getContentUri(null), v);
+ }, getContentUri(null), values);
}
/**
* Removes row from database.
* Caller should call {@link FilteredNumberAsyncQueryHandler#isBlocked} first.
- * @param id the ID of the row to remove, from {@link FilteredNumberAsyncQueryHandler#isBlocked}.
- * Returns to the listener the number of rows affected. Expected value is 1.
+ * @param id The ID of row to remove, from {@link FilteredNumberAsyncQueryHandler#isBlocked}.
*/
public final void unblock(final OnUnblockNumberListener listener, Integer id) {
if (id == null) {
throw new IllegalArgumentException("Null id passed into unblock");
}
- startDelete(NO_TOKEN, new Listener() {
+ unblock(listener, getContentUri(id));
+ }
+
+ /**
+ * Removes row from database.
+ * @param uri The uri of row to remove, from
+ * {@link FilteredNumberAsyncQueryHandler#blockNumber}.
+ */
+ public final void unblock(final OnUnblockNumberListener listener, final Uri uri) {
+ startQuery(NO_TOKEN, new Listener() {
@Override
- public void onDeleteComplete(int token, Object cookie, int result) {
- listener.onDeleteComplete(result);
+ public void onQueryComplete(int token, Object cookie, Cursor cursor) {
+ if (cursor.getCount() != 1) {
+ throw new SQLiteDatabaseCorruptException
+ ("Returned " + cursor.getCount() + " rows for uri "
+ + uri + "where 1 expected.");
+ }
+ cursor.moveToFirst();
+ final ContentValues values = new ContentValues();
+ DatabaseUtils.cursorRowToContentValues(cursor, values);
+ values.remove(FilteredNumberColumns._ID);
+
+ startDelete(NO_TOKEN, new Listener() {
+ @Override
+ public void onDeleteComplete(int token, Object cookie, int result) {
+ listener.onUnblockComplete(result, values);
+ }
+ }, uri, null, null);
}
- }, getContentUri(id), null, null);
+ }, uri, null, null, null, null);
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java b/src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java
new file mode 100644
index 000000000..f94d0f842
--- /dev/null
+++ b/src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2015 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.filterednumber;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.ContentValues;
+import android.content.DialogInterface;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.design.widget.Snackbar;
+import android.view.View;
+
+import com.android.dialer.R;
+import com.android.dialer.database.FilteredNumberAsyncQueryHandler;
+
+public class FilterNumberDialogFragment extends DialogFragment {
+ public static final String BLOCK_DIALOG_FRAGMENT = "blockUnblockNumberDialog";
+
+ private static final String ARG_BLOCK_ID = "argBlockId";
+ private static final String ARG_NORMALIZED_NUMBER = "argNormalizedNumber";
+ private static final String ARG_NUMBER = "argNumber";
+ private static final String ARG_COUNTRY_ISO = "argCountryIso";
+ private static final String ARG_DISPLAY_NUMBER = "argDisplayNumber";
+
+ private FilteredNumberAsyncQueryHandler mHandler;
+
+ public void setQueryHandler (FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler) {
+ mHandler = filteredNumberAsyncQueryHandler;
+ }
+
+ public static FilterNumberDialogFragment newInstance(Integer blockId, String normalizedNumber,
+ String number, String countryIso, String displayNumber) {
+ final FilterNumberDialogFragment fragment = new FilterNumberDialogFragment();
+ final Bundle args = new Bundle();
+ if (blockId != null) {
+ args.putInt(ARG_BLOCK_ID, blockId.intValue());
+ }
+ args.putString(ARG_NORMALIZED_NUMBER, normalizedNumber);
+ args.putString(ARG_NUMBER, number);
+ args.putString(ARG_COUNTRY_ISO, countryIso);
+ args.putString(ARG_DISPLAY_NUMBER, displayNumber);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ super.onCreateDialog(savedInstanceState);
+ final boolean isBlocked = getArguments().containsKey(ARG_BLOCK_ID);
+ final String displayNumber = getArguments().getString(ARG_DISPLAY_NUMBER);
+
+ String message;
+ String okText;
+ if (isBlocked) {
+ message = getString(R.string.unblockNumberConfirmation, displayNumber);
+ okText = getString(R.string.unblockNumberOk);
+ } else {
+ message = getString(R.string.blockNumberConfirmation, displayNumber);
+ okText = getString(R.string.blockNumberOk);
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
+ .setMessage(message)
+ .setPositiveButton(okText, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ if (isBlocked) {
+ unblockNumber();
+ } else {
+ blockNumber();
+ }
+ }
+ })
+ .setNegativeButton(android.R.string.cancel, null);
+ return builder.create();
+ }
+
+ public void blockNumber() {
+ final View view = getActivity().findViewById(R.id.floating_action_button_container);
+ final String displayNumber = getArguments().getString(ARG_DISPLAY_NUMBER);
+ final String message = getString(R.string.snackbar_number_blocked, displayNumber);
+ final String undoMessage = getString(R.string.snackbar_number_unblocked, displayNumber);
+ final FilteredNumberAsyncQueryHandler.OnUnblockNumberListener undoListener =
+ new FilteredNumberAsyncQueryHandler.OnUnblockNumberListener() {
+ @Override
+ public void onUnblockComplete(int rows, ContentValues values) {
+ Snackbar.make(view, undoMessage, Snackbar.LENGTH_LONG).show();
+ }
+ };
+
+ mHandler.blockNumber(
+ new FilteredNumberAsyncQueryHandler.OnBlockNumberListener() {
+ @Override
+ public void onBlockComplete(final Uri uri) {
+ Snackbar.make(view, message, Snackbar.LENGTH_LONG)
+ .setAction(R.string.block_number_undo,
+ // Delete the newly created row on 'undo'.
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mHandler.unblock(undoListener, uri);
+ }
+ })
+ .show();
+ }
+ }, getArguments().getString(ARG_NORMALIZED_NUMBER),
+ getArguments().getString(ARG_NUMBER), getArguments().getString(ARG_COUNTRY_ISO));
+ }
+
+ public void unblockNumber() {
+ final View view = getActivity().findViewById(R.id.floating_action_button_container);
+ final String displayNumber = getArguments().getString(ARG_DISPLAY_NUMBER);
+ final String message = getString(R.string.snackbar_number_unblocked, displayNumber);
+ final String undoMessage = getString(R.string.snackbar_number_blocked, displayNumber);
+ final FilteredNumberAsyncQueryHandler.OnBlockNumberListener undoListener =
+ new FilteredNumberAsyncQueryHandler.OnBlockNumberListener() {
+ @Override
+ public void onBlockComplete(final Uri uri) {
+ Snackbar.make(view, undoMessage, Snackbar.LENGTH_LONG).show();
+ }
+ };
+ mHandler.unblock(
+ new FilteredNumberAsyncQueryHandler.OnUnblockNumberListener() {
+ @Override
+ public void onUnblockComplete(int rows, final ContentValues values) {
+ Snackbar.make(view, message, Snackbar.LENGTH_LONG)
+ .setAction(R.string.block_number_undo,
+ new View.OnClickListener() {
+ // Re-insert the row on 'undo', with a new ID.
+ @Override
+ public void onClick(View view) {
+ mHandler.blockNumber(undoListener, values);
+ }
+ })
+ .show();
+ }
+ }, getArguments().getInt(ARG_BLOCK_ID));
+ }
+} \ No newline at end of file