Home | History | Annotate | Download | only in list
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.dialer.list;
     17 
     18 import android.app.Activity;
     19 import android.os.Bundle;
     20 import android.support.v7.app.ActionBar;
     21 import android.support.v7.app.AppCompatActivity;
     22 import android.telephony.PhoneNumberUtils;
     23 import android.text.Editable;
     24 import android.text.TextUtils;
     25 import android.text.TextWatcher;
     26 import android.util.Log;
     27 import android.util.TypedValue;
     28 import android.view.View;
     29 import android.widget.AdapterView;
     30 import android.widget.EditText;
     31 import android.widget.Toast;
     32 
     33 import com.android.contacts.common.GeoUtil;
     34 import com.android.contacts.common.list.ContactEntryListAdapter;
     35 import com.android.contacts.common.util.ContactDisplayUtils;
     36 import com.android.dialer.R;
     37 import com.android.dialer.database.FilteredNumberAsyncQueryHandler;
     38 import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnCheckBlockedListener;
     39 import com.android.dialer.filterednumber.BlockNumberDialogFragment;
     40 import com.android.dialer.logging.InteractionEvent;
     41 import com.android.dialer.logging.Logger;
     42 import com.android.dialer.widget.SearchEditTextLayout;
     43 
     44 public class BlockedListSearchFragment extends RegularSearchFragment
     45         implements BlockNumberDialogFragment.Callback {
     46     private static final String TAG = BlockedListSearchFragment.class.getSimpleName();
     47 
     48     private static final String KEY_SEARCH_QUERY = "search_query";
     49 
     50     private FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler;
     51 
     52     private EditText mSearchView;
     53 
     54     private final TextWatcher mPhoneSearchQueryTextListener = new TextWatcher() {
     55         @Override
     56         public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
     57 
     58         @Override
     59         public void onTextChanged(CharSequence s, int start, int before, int count) {
     60             setQueryString(s.toString(), false);
     61         }
     62 
     63         @Override
     64         public void afterTextChanged(Editable s) {}
     65     };
     66 
     67     private final SearchEditTextLayout.Callback mSearchLayoutCallback =
     68             new SearchEditTextLayout.Callback() {
     69                 @Override
     70                 public void onBackButtonClicked() {
     71                     getActivity().onBackPressed();
     72                 }
     73 
     74                 @Override
     75                 public void onSearchViewClicked() {
     76                 }
     77             };
     78 
     79     @Override
     80     public void onCreate(Bundle savedInstanceState) {
     81         super.onCreate(savedInstanceState);
     82 
     83         setShowEmptyListForNullQuery(true);
     84         /*
     85          * Pass in the empty string here so ContactEntryListFragment#setQueryString interprets it as
     86          * an empty search query, rather than as an uninitalized value. In the latter case, the
     87          * adapter returned by #createListAdapter is used, which populates the view with contacts.
     88          * Passing in the empty string forces ContactEntryListFragment to interpret it as an empty
     89          * query, which results in showing an empty view
     90          */
     91         setQueryString(getQueryString() == null ? "" : getQueryString(), false);
     92         mFilteredNumberAsyncQueryHandler = new FilteredNumberAsyncQueryHandler(
     93                 getContext().getContentResolver());
     94     }
     95 
     96     @Override
     97     public void onResume() {
     98         super.onResume();
     99 
    100         ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
    101         actionBar.setCustomView(R.layout.search_edittext);
    102         actionBar.setDisplayShowCustomEnabled(true);
    103         actionBar.setDisplayHomeAsUpEnabled(false);
    104         actionBar.setDisplayShowHomeEnabled(false);
    105 
    106         final SearchEditTextLayout searchEditTextLayout = (SearchEditTextLayout) actionBar
    107                 .getCustomView().findViewById(R.id.search_view_container);
    108         searchEditTextLayout.expand(false, true);
    109         searchEditTextLayout.setCallback(mSearchLayoutCallback);
    110         searchEditTextLayout.setBackgroundDrawable(null);
    111 
    112         mSearchView = (EditText) searchEditTextLayout.findViewById(R.id.search_view);
    113         mSearchView.addTextChangedListener(mPhoneSearchQueryTextListener);
    114         mSearchView.setHint(R.string.block_number_search_hint);
    115 
    116         searchEditTextLayout.findViewById(R.id.search_box_expanded)
    117                 .setBackgroundColor(getContext().getResources().getColor(android.R.color.white));
    118 
    119         if (!TextUtils.isEmpty(getQueryString())) {
    120             mSearchView.setText(getQueryString());
    121         }
    122 
    123         // TODO: Don't set custom text size; use default search text size.
    124         mSearchView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
    125                 getResources().getDimension(R.dimen.blocked_number_search_text_size));
    126     }
    127 
    128     @Override
    129     protected ContactEntryListAdapter createListAdapter() {
    130         BlockedListSearchAdapter adapter = new BlockedListSearchAdapter(getActivity());
    131         adapter.setDisplayPhotos(true);
    132         // Don't show SIP addresses.
    133         adapter.setUseCallableUri(false);
    134         // Keep in sync with the queryString set in #onCreate
    135         adapter.setQueryString(getQueryString() == null ? "" : getQueryString());
    136         return adapter;
    137     }
    138 
    139 
    140     @Override
    141     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    142         super.onItemClick(parent, view, position, id);
    143         final int adapterPosition = position - getListView().getHeaderViewsCount();
    144         final BlockedListSearchAdapter adapter = (BlockedListSearchAdapter) getAdapter();
    145         final int shortcutType = adapter.getShortcutTypeFromPosition(adapterPosition);
    146         final Integer blockId = (Integer) view.getTag(R.id.block_id);
    147         final String number;
    148         switch (shortcutType) {
    149             case DialerPhoneNumberListAdapter.SHORTCUT_INVALID:
    150                 // Handles click on a search result, either contact or nearby places result.
    151                 number = adapter.getPhoneNumber(adapterPosition);
    152                 blockContactNumber(number, blockId);
    153                 break;
    154             case DialerPhoneNumberListAdapter.SHORTCUT_BLOCK_NUMBER:
    155                 // Handles click on 'Block number' shortcut to add the user query as a number.
    156                 number = adapter.getQueryString();
    157                 blockNumber(number);
    158                 break;
    159             default:
    160                 Log.w(TAG, "Ignoring unsupported shortcut type: " + shortcutType);
    161                 break;
    162         }
    163     }
    164 
    165     @Override
    166     protected void onItemClick(int position, long id) {
    167         // Prevent SearchFragment.onItemClicked from being called.
    168     }
    169 
    170     private void blockNumber(final String number) {
    171         final String countryIso = GeoUtil.getCurrentCountryIso(getContext());
    172         final OnCheckBlockedListener onCheckListener = new OnCheckBlockedListener() {
    173             @Override
    174             public void onCheckComplete(Integer id) {
    175                 if (id == null) {
    176                     BlockNumberDialogFragment.show(
    177                             id,
    178                             number,
    179                             countryIso,
    180                             PhoneNumberUtils.formatNumber(number, countryIso),
    181                             R.id.blocked_numbers_activity_container,
    182                             getFragmentManager(),
    183                             BlockedListSearchFragment.this);
    184                 } else {
    185                     Toast.makeText(getContext(),
    186                             ContactDisplayUtils.getTtsSpannedPhoneNumber(getResources(),
    187                                     R.string.alreadyBlocked, number),
    188                             Toast.LENGTH_SHORT).show();
    189                 }
    190             }
    191         };
    192         final boolean success = mFilteredNumberAsyncQueryHandler.isBlockedNumber(
    193                 onCheckListener, number, countryIso);
    194         if (!success) {
    195             Toast.makeText(getContext(),
    196                     ContactDisplayUtils.getTtsSpannedPhoneNumber(
    197                             getResources(), R.string.invalidNumber, number),
    198                     Toast.LENGTH_SHORT).show();
    199         }
    200     }
    201 
    202     @Override
    203     public void onFilterNumberSuccess() {
    204         Logger.logInteraction(InteractionEvent.BLOCK_NUMBER_MANAGEMENT_SCREEN);
    205         goBack();
    206     }
    207 
    208     @Override
    209     public void onUnfilterNumberSuccess() {
    210         Log.wtf(TAG, "Unblocked a number from the BlockedListSearchFragment");
    211         goBack();
    212     }
    213 
    214     private void goBack() {
    215         Activity activity = getActivity();
    216         if (activity == null) {
    217             return;
    218         }
    219         activity.onBackPressed();
    220     }
    221 
    222     @Override
    223     public void onChangeFilteredNumberUndo() {
    224         getAdapter().notifyDataSetChanged();
    225     }
    226 
    227     private void blockContactNumber(final String number, final Integer blockId) {
    228         if (blockId != null) {
    229             Toast.makeText(getContext(), ContactDisplayUtils.getTtsSpannedPhoneNumber(
    230                             getResources(), R.string.alreadyBlocked, number),
    231                     Toast.LENGTH_SHORT).show();
    232             return;
    233         }
    234 
    235         BlockNumberDialogFragment.show(
    236                 blockId,
    237                 number,
    238                 GeoUtil.getCurrentCountryIso(getContext()),
    239                 number,
    240                 R.id.blocked_numbers_activity_container,
    241                 getFragmentManager(),
    242                 this);
    243     }
    244 }
    245