From 21e24b6d9355e5e64a594b3b32cb4c8301e3330b Mon Sep 17 00:00:00 2001 From: calderwoodra Date: Tue, 5 Sep 2017 18:49:07 -0700 Subject: Automated g4 rollback of changelist 167310802. *** Reason for rollback *** Turns out blocked number activity is actually used for devices on M. *** Original change description *** Removes the unused dialer/app/filterednumber package. *** Test: n/a PiperOrigin-RevId: 167663280 Change-Id: I6af1fc7d6eb61f946d4fba255fe7374bcdee0e72 --- java/com/android/dialer/app/AndroidManifest.xml | 12 + .../app/filterednumber/BlockedNumbersAdapter.java | 96 ++++++++ .../app/filterednumber/BlockedNumbersFragment.java | 272 +++++++++++++++++++++ .../BlockedNumbersSettingsActivity.java | 142 +++++++++++ .../dialer/app/filterednumber/NumbersAdapter.java | 140 +++++++++++ .../filterednumber/ViewNumbersToImportAdapter.java | 57 +++++ .../ViewNumbersToImportFragment.java | 131 ++++++++++ .../dialer/app/list/BlockedListSearchFragment.java | 248 +++++++++++++++++++ 8 files changed, 1098 insertions(+) create mode 100644 java/com/android/dialer/app/filterednumber/BlockedNumbersAdapter.java create mode 100644 java/com/android/dialer/app/filterednumber/BlockedNumbersFragment.java create mode 100644 java/com/android/dialer/app/filterednumber/BlockedNumbersSettingsActivity.java create mode 100644 java/com/android/dialer/app/filterednumber/NumbersAdapter.java create mode 100644 java/com/android/dialer/app/filterednumber/ViewNumbersToImportAdapter.java create mode 100644 java/com/android/dialer/app/filterednumber/ViewNumbersToImportFragment.java create mode 100644 java/com/android/dialer/app/list/BlockedListSearchFragment.java (limited to 'java/com/android/dialer') diff --git a/java/com/android/dialer/app/AndroidManifest.xml b/java/com/android/dialer/app/AndroidManifest.xml index 1c04b764c..4200082a6 100644 --- a/java/com/android/dialer/app/AndroidManifest.xml +++ b/java/com/android/dialer/app/AndroidManifest.xml @@ -60,6 +60,18 @@ + + + + + + + , + View.OnClickListener, + VisualVoicemailEnabledChecker.Callback { + + private static final char ADD_BLOCKED_NUMBER_ICON_LETTER = '+'; + protected View migratePromoView; + private BlockedNumbersMigrator blockedNumbersMigratorForTest; + private TextView blockedNumbersText; + private TextView footerText; + private BlockedNumbersAdapter mAdapter; + private VisualVoicemailEnabledChecker mVoicemailEnabledChecker; + private View mImportSettings; + private View mBlockedNumbersDisabledForEmergency; + private View mBlockedNumberListDivider; + + @Override + public Context getContext() { + return getActivity(); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + LayoutInflater inflater = + (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + getListView().addHeaderView(inflater.inflate(R.layout.blocked_number_header, null)); + getListView().addFooterView(inflater.inflate(R.layout.blocked_number_footer, null)); + //replace the icon for add number with LetterTileDrawable(), so it will have identical style + ImageView addNumberIcon = (ImageView) getActivity().findViewById(R.id.add_number_icon); + LetterTileDrawable drawable = new LetterTileDrawable(getResources()); + drawable.setLetter(ADD_BLOCKED_NUMBER_ICON_LETTER); + drawable.setColor( + ActivityCompat.getColor(getActivity(), R.color.add_blocked_number_icon_color)); + drawable.setIsCircular(true); + addNumberIcon.setImageDrawable(drawable); + + if (mAdapter == null) { + mAdapter = + BlockedNumbersAdapter.newBlockedNumbersAdapter( + getContext(), getActivity().getFragmentManager()); + } + setListAdapter(mAdapter); + + blockedNumbersText = (TextView) getListView().findViewById(R.id.blocked_number_text_view); + migratePromoView = getListView().findViewById(R.id.migrate_promo); + getListView().findViewById(R.id.migrate_promo_allow_button).setOnClickListener(this); + mImportSettings = getListView().findViewById(R.id.import_settings); + mBlockedNumbersDisabledForEmergency = + getListView().findViewById(R.id.blocked_numbers_disabled_for_emergency); + mBlockedNumberListDivider = getActivity().findViewById(R.id.blocked_number_list_divider); + getListView().findViewById(R.id.import_button).setOnClickListener(this); + getListView().findViewById(R.id.view_numbers_button).setOnClickListener(this); + getListView().findViewById(R.id.add_number_linear_layout).setOnClickListener(this); + + footerText = (TextView) getActivity().findViewById(R.id.blocked_number_footer_textview); + mVoicemailEnabledChecker = new VisualVoicemailEnabledChecker(getContext(), this); + mVoicemailEnabledChecker.asyncUpdate(); + updateActiveVoicemailProvider(); + } + + @Override + public void onDestroy() { + setListAdapter(null); + super.onDestroy(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getLoaderManager().initLoader(0, null, this); + } + + @Override + public void onResume() { + super.onResume(); + + ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); + ColorDrawable backgroundDrawable = + new ColorDrawable(ActivityCompat.getColor(getActivity(), R.color.dialer_theme_color)); + actionBar.setBackgroundDrawable(backgroundDrawable); + actionBar.setDisplayShowCustomEnabled(false); + actionBar.setDisplayHomeAsUpEnabled(true); + actionBar.setDisplayShowHomeEnabled(true); + actionBar.setDisplayShowTitleEnabled(true); + actionBar.setTitle(R.string.manage_blocked_numbers_label); + + // If the device can use the framework blocking solution, users should not be able to add + // new blocked numbers from the Blocked Management UI. They will be shown a promo card + // asking them to migrate to new blocking instead. + if (FilteredNumberCompat.canUseNewFiltering()) { + migratePromoView.setVisibility(View.VISIBLE); + blockedNumbersText.setVisibility(View.GONE); + getListView().findViewById(R.id.add_number_linear_layout).setVisibility(View.GONE); + getListView().findViewById(R.id.add_number_linear_layout).setOnClickListener(null); + mBlockedNumberListDivider.setVisibility(View.GONE); + mImportSettings.setVisibility(View.GONE); + getListView().findViewById(R.id.import_button).setOnClickListener(null); + getListView().findViewById(R.id.view_numbers_button).setOnClickListener(null); + mBlockedNumbersDisabledForEmergency.setVisibility(View.GONE); + footerText.setVisibility(View.GONE); + } else { + FilteredNumbersUtil.checkForSendToVoicemailContact( + getActivity(), + new CheckForSendToVoicemailContactListener() { + @Override + public void onComplete(boolean hasSendToVoicemailContact) { + final int visibility = hasSendToVoicemailContact ? View.VISIBLE : View.GONE; + mImportSettings.setVisibility(visibility); + } + }); + } + + // All views except migrate and the block list are hidden when new filtering is available + if (!FilteredNumberCompat.canUseNewFiltering() + && FilteredNumbersUtil.hasRecentEmergencyCall(getContext())) { + mBlockedNumbersDisabledForEmergency.setVisibility(View.VISIBLE); + } else { + mBlockedNumbersDisabledForEmergency.setVisibility(View.GONE); + } + + mVoicemailEnabledChecker.asyncUpdate(); + } + + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.blocked_number_fragment, container, false); + } + + @Override + public Loader onCreateLoader(int id, Bundle args) { + final String[] projection = { + FilteredNumberContract.FilteredNumberColumns._ID, + FilteredNumberContract.FilteredNumberColumns.COUNTRY_ISO, + FilteredNumberContract.FilteredNumberColumns.NUMBER, + FilteredNumberContract.FilteredNumberColumns.NORMALIZED_NUMBER + }; + final String selection = + FilteredNumberContract.FilteredNumberColumns.TYPE + + "=" + + FilteredNumberContract.FilteredNumberTypes.BLOCKED_NUMBER; + return new CursorLoader( + getContext(), + FilteredNumberContract.FilteredNumber.CONTENT_URI, + projection, + selection, + null, + null); + } + + @Override + public void onLoadFinished(Loader loader, Cursor data) { + mAdapter.swapCursor(data); + if (FilteredNumberCompat.canUseNewFiltering() || data.getCount() == 0) { + mBlockedNumberListDivider.setVisibility(View.INVISIBLE); + } else { + mBlockedNumberListDivider.setVisibility(View.VISIBLE); + } + } + + @Override + public void onLoaderReset(Loader loader) { + mAdapter.swapCursor(null); + } + + @Override + public void onClick(final View view) { + final BlockedNumbersSettingsActivity activity = (BlockedNumbersSettingsActivity) getActivity(); + if (activity == null) { + return; + } + + int resId = view.getId(); + if (resId == R.id.add_number_linear_layout) { + activity.showSearchUi(); + } else if (resId == R.id.view_numbers_button) { + activity.showNumbersToImportPreviewUi(); + } else if (resId == R.id.import_button) { + FilteredNumbersUtil.importSendToVoicemailContacts( + activity, + new ImportSendToVoicemailContactsListener() { + @Override + public void onImportComplete() { + mImportSettings.setVisibility(View.GONE); + } + }); + } else if (resId == R.id.migrate_promo_allow_button) { + view.setEnabled(false); + (blockedNumbersMigratorForTest != null + ? blockedNumbersMigratorForTest + : new BlockedNumbersMigrator(getContext())) + .migrate( + new Listener() { + @Override + public void onComplete() { + getContext() + .startActivity( + FilteredNumberCompat.createManageBlockedNumbersIntent(getContext())); + // Remove this activity from the backstack + activity.finish(); + } + }); + } + } + + @Override + public void onVisualVoicemailEnabledStatusChanged(boolean newStatus) { + updateActiveVoicemailProvider(); + } + + private void updateActiveVoicemailProvider() { + if (getActivity() == null || getActivity().isFinishing()) { + return; + } + if (mVoicemailEnabledChecker.isVisualVoicemailEnabled()) { + footerText.setText(R.string.block_number_footer_message_vvm); + } else { + footerText.setText(R.string.block_number_footer_message_no_vvm); + } + } + + void setBlockedNumbersMigratorForTest(BlockedNumbersMigrator blockedNumbersMigrator) { + blockedNumbersMigratorForTest = blockedNumbersMigrator; + } +} diff --git a/java/com/android/dialer/app/filterednumber/BlockedNumbersSettingsActivity.java b/java/com/android/dialer/app/filterednumber/BlockedNumbersSettingsActivity.java new file mode 100644 index 000000000..858d28355 --- /dev/null +++ b/java/com/android/dialer/app/filterednumber/BlockedNumbersSettingsActivity.java @@ -0,0 +1,142 @@ +/* + * 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.app.filterednumber; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.view.MenuItem; +import com.android.dialer.app.R; +import com.android.dialer.app.list.BlockedListSearchFragment; +import com.android.dialer.app.list.SearchFragment; +import com.android.dialer.logging.Logger; +import com.android.dialer.logging.ScreenEvent; + +/** TODO(calderwoodra): documentation */ +public class BlockedNumbersSettingsActivity extends AppCompatActivity + implements SearchFragment.HostInterface { + + private static final String TAG_BLOCKED_MANAGEMENT_FRAGMENT = "blocked_management"; + private static final String TAG_BLOCKED_SEARCH_FRAGMENT = "blocked_search"; + private static final String TAG_VIEW_NUMBERS_TO_IMPORT_FRAGMENT = "view_numbers_to_import"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.blocked_numbers_activity); + + // If savedInstanceState != null, the Activity will automatically restore the last fragment. + if (savedInstanceState == null) { + showManagementUi(); + } + } + + /** Shows fragment with the list of currently blocked numbers and settings related to blocking. */ + public void showManagementUi() { + BlockedNumbersFragment fragment = + (BlockedNumbersFragment) + getFragmentManager().findFragmentByTag(TAG_BLOCKED_MANAGEMENT_FRAGMENT); + if (fragment == null) { + fragment = new BlockedNumbersFragment(); + } + + getFragmentManager() + .beginTransaction() + .replace(R.id.blocked_numbers_activity_container, fragment, TAG_BLOCKED_MANAGEMENT_FRAGMENT) + .commit(); + + Logger.get(this).logScreenView(ScreenEvent.Type.BLOCKED_NUMBER_MANAGEMENT, this); + } + + /** Shows fragment with search UI for browsing/finding numbers to block. */ + public void showSearchUi() { + BlockedListSearchFragment fragment = + (BlockedListSearchFragment) + getFragmentManager().findFragmentByTag(TAG_BLOCKED_SEARCH_FRAGMENT); + if (fragment == null) { + fragment = new BlockedListSearchFragment(); + fragment.setHasOptionsMenu(false); + fragment.setShowEmptyListForNullQuery(true); + fragment.setDirectorySearchEnabled(false); + } + + getFragmentManager() + .beginTransaction() + .replace(R.id.blocked_numbers_activity_container, fragment, TAG_BLOCKED_SEARCH_FRAGMENT) + .addToBackStack(null) + .commit(); + + Logger.get(this).logScreenView(ScreenEvent.Type.BLOCKED_NUMBER_ADD_NUMBER, this); + } + + /** + * Shows fragment with UI to preview the numbers of contacts currently marked as send-to-voicemail + * in Contacts. These numbers can be imported into Dialer's blocked number list. + */ + public void showNumbersToImportPreviewUi() { + ViewNumbersToImportFragment fragment = + (ViewNumbersToImportFragment) + getFragmentManager().findFragmentByTag(TAG_VIEW_NUMBERS_TO_IMPORT_FRAGMENT); + if (fragment == null) { + fragment = new ViewNumbersToImportFragment(); + } + + getFragmentManager() + .beginTransaction() + .replace( + R.id.blocked_numbers_activity_container, fragment, TAG_VIEW_NUMBERS_TO_IMPORT_FRAGMENT) + .addToBackStack(null) + .commit(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + onBackPressed(); + return true; + } + return false; + } + + @Override + public void onBackPressed() { + // TODO: Achieve back navigation without overriding onBackPressed. + if (getFragmentManager().getBackStackEntryCount() > 0) { + getFragmentManager().popBackStack(); + } else { + super.onBackPressed(); + } + } + + @Override + public boolean isActionBarShowing() { + return false; + } + + @Override + public boolean isDialpadShown() { + return false; + } + + @Override + public int getDialpadHeight() { + return 0; + } + + @Override + public int getActionBarHeight() { + return 0; + } +} diff --git a/java/com/android/dialer/app/filterednumber/NumbersAdapter.java b/java/com/android/dialer/app/filterednumber/NumbersAdapter.java new file mode 100644 index 000000000..938a78479 --- /dev/null +++ b/java/com/android/dialer/app/filterednumber/NumbersAdapter.java @@ -0,0 +1,140 @@ +/* + * 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.app.filterednumber; + +import android.app.FragmentManager; +import android.content.Context; +import android.provider.ContactsContract; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.text.BidiFormatter; +import android.text.TextDirectionHeuristics; +import android.text.TextUtils; +import android.view.View; +import android.widget.QuickContactBadge; +import android.widget.SimpleCursorAdapter; +import android.widget.TextView; +import com.android.dialer.app.R; +import com.android.dialer.compat.CompatUtils; +import com.android.dialer.contactphoto.ContactPhotoManager; +import com.android.dialer.contactphoto.ContactPhotoManager.DefaultImageRequest; +import com.android.dialer.lettertile.LetterTileDrawable; +import com.android.dialer.phonenumbercache.ContactInfo; +import com.android.dialer.phonenumbercache.ContactInfoHelper; +import com.android.dialer.phonenumberutil.PhoneNumberHelper; +import com.android.dialer.util.UriUtils; + +/** TODO(calderwoodra): documentation */ +public class NumbersAdapter extends SimpleCursorAdapter { + + private final Context mContext; + private final FragmentManager mFragmentManager; + private final ContactInfoHelper mContactInfoHelper; + private final BidiFormatter mBidiFormatter = BidiFormatter.getInstance(); + private final ContactPhotoManager mContactPhotoManager; + + public NumbersAdapter( + Context context, + FragmentManager fragmentManager, + ContactInfoHelper contactInfoHelper, + ContactPhotoManager contactPhotoManager) { + super(context, R.layout.blocked_number_item, null, new String[] {}, new int[] {}, 0); + mContext = context; + mFragmentManager = fragmentManager; + mContactInfoHelper = contactInfoHelper; + mContactPhotoManager = contactPhotoManager; + } + + public void updateView(View view, String number, String countryIso) { + final TextView callerName = (TextView) view.findViewById(R.id.caller_name); + final TextView callerNumber = (TextView) view.findViewById(R.id.caller_number); + final QuickContactBadge quickContactBadge = + (QuickContactBadge) view.findViewById(R.id.quick_contact_photo); + quickContactBadge.setOverlay(null); + if (CompatUtils.hasPrioritizedMimeType()) { + quickContactBadge.setPrioritizedMimeType(Phone.CONTENT_ITEM_TYPE); + } + + ContactInfo info = mContactInfoHelper.lookupNumber(number, countryIso); + if (info == null) { + info = new ContactInfo(); + info.number = number; + } + final CharSequence locationOrType = getNumberTypeOrLocation(info); + final String displayNumber = getDisplayNumber(info); + final String displayNumberStr = + mBidiFormatter.unicodeWrap(displayNumber, TextDirectionHeuristics.LTR); + + String nameForDefaultImage; + if (!TextUtils.isEmpty(info.name)) { + nameForDefaultImage = info.name; + callerName.setText(info.name); + callerNumber.setText(locationOrType + " " + displayNumberStr); + } else { + nameForDefaultImage = displayNumber; + callerName.setText(displayNumberStr); + if (!TextUtils.isEmpty(locationOrType)) { + callerNumber.setText(locationOrType); + callerNumber.setVisibility(View.VISIBLE); + } else { + callerNumber.setVisibility(View.GONE); + } + } + loadContactPhoto(info, nameForDefaultImage, quickContactBadge); + } + + private void loadContactPhoto(ContactInfo info, String displayName, QuickContactBadge badge) { + final String lookupKey = + info.lookupUri == null ? null : UriUtils.getLookupKeyFromUri(info.lookupUri); + final int contactType = + mContactInfoHelper.isBusiness(info.sourceType) + ? LetterTileDrawable.TYPE_BUSINESS + : LetterTileDrawable.TYPE_DEFAULT; + final DefaultImageRequest request = + new DefaultImageRequest(displayName, lookupKey, contactType, true /* isCircular */); + badge.assignContactUri(info.lookupUri); + badge.setContentDescription( + mContext.getResources().getString(R.string.description_contact_details, displayName)); + mContactPhotoManager.loadDirectoryPhoto( + badge, info.photoUri, false /* darkTheme */, true /* isCircular */, request); + } + + private String getDisplayNumber(ContactInfo info) { + if (!TextUtils.isEmpty(info.formattedNumber)) { + return info.formattedNumber; + } else if (!TextUtils.isEmpty(info.number)) { + return info.number; + } else { + return ""; + } + } + + private CharSequence getNumberTypeOrLocation(ContactInfo info) { + if (!TextUtils.isEmpty(info.name)) { + return ContactsContract.CommonDataKinds.Phone.getTypeLabel( + mContext.getResources(), info.type, info.label); + } else { + return PhoneNumberHelper.getGeoDescription(mContext, info.number); + } + } + + protected Context getContext() { + return mContext; + } + + protected FragmentManager getFragmentManager() { + return mFragmentManager; + } +} diff --git a/java/com/android/dialer/app/filterednumber/ViewNumbersToImportAdapter.java b/java/com/android/dialer/app/filterednumber/ViewNumbersToImportAdapter.java new file mode 100644 index 000000000..106c4fb71 --- /dev/null +++ b/java/com/android/dialer/app/filterednumber/ViewNumbersToImportAdapter.java @@ -0,0 +1,57 @@ +/* + * 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.app.filterednumber; + +import android.app.FragmentManager; +import android.content.Context; +import android.database.Cursor; +import android.view.View; +import com.android.dialer.app.R; +import com.android.dialer.blocking.FilteredNumbersUtil; +import com.android.dialer.contactphoto.ContactPhotoManager; +import com.android.dialer.location.GeoUtil; +import com.android.dialer.phonenumbercache.ContactInfoHelper; + +/** TODO(calderwoodra): documentation */ +public class ViewNumbersToImportAdapter extends NumbersAdapter { + + private ViewNumbersToImportAdapter( + Context context, + FragmentManager fragmentManager, + ContactInfoHelper contactInfoHelper, + ContactPhotoManager contactPhotoManager) { + super(context, fragmentManager, contactInfoHelper, contactPhotoManager); + } + + public static ViewNumbersToImportAdapter newViewNumbersToImportAdapter( + Context context, FragmentManager fragmentManager) { + return new ViewNumbersToImportAdapter( + context, + fragmentManager, + new ContactInfoHelper(context, GeoUtil.getCurrentCountryIso(context)), + ContactPhotoManager.getInstance(context)); + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + super.bindView(view, context, cursor); + + final String number = cursor.getString(FilteredNumbersUtil.PhoneQuery.NUMBER_COLUMN_INDEX); + + view.findViewById(R.id.delete_button).setVisibility(View.GONE); + updateView(view, number, null /* countryIso */); + } +} diff --git a/java/com/android/dialer/app/filterednumber/ViewNumbersToImportFragment.java b/java/com/android/dialer/app/filterednumber/ViewNumbersToImportFragment.java new file mode 100644 index 000000000..1de768219 --- /dev/null +++ b/java/com/android/dialer/app/filterednumber/ViewNumbersToImportFragment.java @@ -0,0 +1,131 @@ +/* + * 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.app.filterednumber; + +import android.app.ListFragment; +import android.app.LoaderManager; +import android.content.Context; +import android.content.CursorLoader; +import android.content.Loader; +import android.database.Cursor; +import android.os.Bundle; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatActivity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import com.android.dialer.app.R; +import com.android.dialer.blocking.FilteredNumbersUtil; +import com.android.dialer.blocking.FilteredNumbersUtil.ImportSendToVoicemailContactsListener; + +/** TODO(calderwoodra): documentation */ +public class ViewNumbersToImportFragment extends ListFragment + implements LoaderManager.LoaderCallbacks, View.OnClickListener { + + private ViewNumbersToImportAdapter mAdapter; + + @Override + public Context getContext() { + return getActivity(); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + if (mAdapter == null) { + mAdapter = + ViewNumbersToImportAdapter.newViewNumbersToImportAdapter( + getContext(), getActivity().getFragmentManager()); + } + setListAdapter(mAdapter); + } + + @Override + public void onDestroy() { + setListAdapter(null); + super.onDestroy(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getLoaderManager().initLoader(0, null, this); + } + + @Override + public void onResume() { + super.onResume(); + + ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); + actionBar.setTitle(R.string.import_send_to_voicemail_numbers_label); + actionBar.setDisplayShowCustomEnabled(false); + actionBar.setDisplayHomeAsUpEnabled(true); + actionBar.setDisplayShowHomeEnabled(true); + actionBar.setDisplayShowTitleEnabled(true); + + getActivity().findViewById(R.id.cancel_button).setOnClickListener(this); + getActivity().findViewById(R.id.import_button).setOnClickListener(this); + } + + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.view_numbers_to_import_fragment, container, false); + } + + @Override + public Loader onCreateLoader(int id, Bundle args) { + final CursorLoader cursorLoader = + new CursorLoader( + getContext(), + Phone.CONTENT_URI, + FilteredNumbersUtil.PhoneQuery.PROJECTION, + FilteredNumbersUtil.PhoneQuery.SELECT_SEND_TO_VOICEMAIL_TRUE, + null, + null); + return cursorLoader; + } + + @Override + public void onLoadFinished(Loader loader, Cursor data) { + mAdapter.swapCursor(data); + } + + @Override + public void onLoaderReset(Loader loader) { + mAdapter.swapCursor(null); + } + + @Override + public void onClick(final View view) { + if (view.getId() == R.id.import_button) { + FilteredNumbersUtil.importSendToVoicemailContacts( + getContext(), + new ImportSendToVoicemailContactsListener() { + @Override + public void onImportComplete() { + if (getActivity() != null) { + getActivity().onBackPressed(); + } + } + }); + } else if (view.getId() == R.id.cancel_button) { + getActivity().onBackPressed(); + } + } +} diff --git a/java/com/android/dialer/app/list/BlockedListSearchFragment.java b/java/com/android/dialer/app/list/BlockedListSearchFragment.java new file mode 100644 index 000000000..bef5af713 --- /dev/null +++ b/java/com/android/dialer/app/list/BlockedListSearchFragment.java @@ -0,0 +1,248 @@ +/* + * 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.app.list; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatActivity; +import android.telephony.PhoneNumberUtils; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.TypedValue; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.Toast; +import com.android.contacts.common.list.ContactEntryListAdapter; +import com.android.contacts.common.util.ContactDisplayUtils; +import com.android.dialer.app.R; +import com.android.dialer.app.widget.SearchEditTextLayout; +import com.android.dialer.blocking.BlockNumberDialogFragment; +import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler; +import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler.OnCheckBlockedListener; +import com.android.dialer.common.LogUtil; +import com.android.dialer.location.GeoUtil; +import com.android.dialer.logging.InteractionEvent; +import com.android.dialer.logging.Logger; + +/** TODO(calderwoodra): documentation */ +public class BlockedListSearchFragment extends RegularSearchFragment + implements BlockNumberDialogFragment.Callback { + + private final TextWatcher mPhoneSearchQueryTextListener = + new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + setQueryString(s.toString()); + } + + @Override + public void afterTextChanged(Editable s) {} + }; + private final SearchEditTextLayout.Callback mSearchLayoutCallback = + new SearchEditTextLayout.Callback() { + @Override + public void onBackButtonClicked() { + getActivity().onBackPressed(); + } + + @Override + public void onSearchViewClicked() {} + }; + private FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler; + private EditText mSearchView; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setShowEmptyListForNullQuery(true); + /* + * Pass in the empty string here so ContactEntryListFragment#setQueryString interprets it as + * an empty search query, rather than as an uninitalized value. In the latter case, the + * adapter returned by #createListAdapter is used, which populates the view with contacts. + * Passing in the empty string forces ContactEntryListFragment to interpret it as an empty + * query, which results in showing an empty view + */ + setQueryString(getQueryString() == null ? "" : getQueryString()); + mFilteredNumberAsyncQueryHandler = new FilteredNumberAsyncQueryHandler(getContext()); + } + + @Override + public void onResume() { + super.onResume(); + + ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); + actionBar.setCustomView(R.layout.search_edittext); + actionBar.setDisplayShowCustomEnabled(true); + actionBar.setDisplayHomeAsUpEnabled(false); + actionBar.setDisplayShowHomeEnabled(false); + + final SearchEditTextLayout searchEditTextLayout = + (SearchEditTextLayout) actionBar.getCustomView().findViewById(R.id.search_view_container); + searchEditTextLayout.expand(false, true); + searchEditTextLayout.setCallback(mSearchLayoutCallback); + searchEditTextLayout.setBackgroundDrawable(null); + + mSearchView = (EditText) searchEditTextLayout.findViewById(R.id.search_view); + mSearchView.addTextChangedListener(mPhoneSearchQueryTextListener); + mSearchView.setHint(R.string.block_number_search_hint); + + searchEditTextLayout + .findViewById(R.id.search_box_expanded) + .setBackgroundColor(getContext().getResources().getColor(android.R.color.white)); + + if (!TextUtils.isEmpty(getQueryString())) { + mSearchView.setText(getQueryString()); + } + + // TODO: Don't set custom text size; use default search text size. + mSearchView.setTextSize( + TypedValue.COMPLEX_UNIT_PX, + getResources().getDimension(R.dimen.blocked_number_search_text_size)); + } + + @Override + protected ContactEntryListAdapter createListAdapter() { + BlockedListSearchAdapter adapter = new BlockedListSearchAdapter(getActivity()); + adapter.setDisplayPhotos(true); + // Don't show SIP addresses. + adapter.setUseCallableUri(false); + // Keep in sync with the queryString set in #onCreate + adapter.setQueryString(getQueryString() == null ? "" : getQueryString()); + return adapter; + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + super.onItemClick(parent, view, position, id); + final int adapterPosition = position - getListView().getHeaderViewsCount(); + final BlockedListSearchAdapter adapter = (BlockedListSearchAdapter) getAdapter(); + final int shortcutType = adapter.getShortcutTypeFromPosition(adapterPosition); + final Integer blockId = (Integer) view.getTag(R.id.block_id); + final String number; + switch (shortcutType) { + case DialerPhoneNumberListAdapter.SHORTCUT_INVALID: + // Handles click on a search result, either contact or nearby places result. + number = adapter.getPhoneNumber(adapterPosition); + blockContactNumber(number, blockId); + break; + case DialerPhoneNumberListAdapter.SHORTCUT_BLOCK_NUMBER: + // Handles click on 'Block number' shortcut to add the user query as a number. + number = adapter.getQueryString(); + blockNumber(number); + break; + default: + LogUtil.w( + "BlockedListSearchFragment.onItemClick", + "ignoring unsupported shortcut type: " + shortcutType); + break; + } + } + + @Override + protected void onItemClick(int position, long id) { + // Prevent SearchFragment.onItemClicked from being called. + } + + private void blockNumber(final String number) { + final String countryIso = GeoUtil.getCurrentCountryIso(getContext()); + final OnCheckBlockedListener onCheckListener = + new OnCheckBlockedListener() { + @Override + public void onCheckComplete(Integer id) { + if (id == null) { + BlockNumberDialogFragment.show( + id, + number, + countryIso, + PhoneNumberUtils.formatNumber(number, countryIso), + R.id.blocked_numbers_activity_container, + getFragmentManager(), + BlockedListSearchFragment.this); + } else if (id == FilteredNumberAsyncQueryHandler.INVALID_ID) { + Toast.makeText( + getContext(), + ContactDisplayUtils.getTtsSpannedPhoneNumber( + getResources(), R.string.invalidNumber, number), + Toast.LENGTH_SHORT) + .show(); + } else { + Toast.makeText( + getContext(), + ContactDisplayUtils.getTtsSpannedPhoneNumber( + getResources(), R.string.alreadyBlocked, number), + Toast.LENGTH_SHORT) + .show(); + } + } + }; + mFilteredNumberAsyncQueryHandler.isBlockedNumber(onCheckListener, number, countryIso); + } + + @Override + public void onFilterNumberSuccess() { + Logger.get(getContext()).logInteraction(InteractionEvent.Type.BLOCK_NUMBER_MANAGEMENT_SCREEN); + goBack(); + } + + @Override + public void onUnfilterNumberSuccess() { + LogUtil.e( + "BlockedListSearchFragment.onUnfilterNumberSuccess", + "unblocked a number from the BlockedListSearchFragment"); + goBack(); + } + + private void goBack() { + Activity activity = getActivity(); + if (activity == null) { + return; + } + activity.onBackPressed(); + } + + @Override + public void onChangeFilteredNumberUndo() { + getAdapter().notifyDataSetChanged(); + } + + private void blockContactNumber(final String number, final Integer blockId) { + if (blockId != null) { + Toast.makeText( + getContext(), + ContactDisplayUtils.getTtsSpannedPhoneNumber( + getResources(), R.string.alreadyBlocked, number), + Toast.LENGTH_SHORT) + .show(); + return; + } + + BlockNumberDialogFragment.show( + blockId, + number, + GeoUtil.getCurrentCountryIso(getContext()), + number, + R.id.blocked_numbers_activity_container, + getFragmentManager(), + this); + } +} -- cgit v1.2.3