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.app.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.TypedValue;
     27 import android.view.View;
     28 import android.widget.AdapterView;
     29 import android.widget.EditText;
     30 import android.widget.Toast;
     31 import com.android.contacts.common.list.ContactEntryListAdapter;
     32 import com.android.contacts.common.util.ContactDisplayUtils;
     33 import com.android.dialer.app.R;
     34 import com.android.dialer.app.widget.SearchEditTextLayout;
     35 import com.android.dialer.blocking.BlockNumberDialogFragment;
     36 import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
     37 import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler.OnCheckBlockedListener;
     38 import com.android.dialer.common.LogUtil;
     39 import com.android.dialer.location.GeoUtil;
     40 import com.android.dialer.logging.InteractionEvent;
     41 import com.android.dialer.logging.Logger;
     42 
     43 public class BlockedListSearchFragment extends RegularSearchFragment
     44     implements BlockNumberDialogFragment.Callback {
     45 
     46   private final TextWatcher mPhoneSearchQueryTextListener =
     47       new TextWatcher() {
     48         @Override
     49         public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
     50 
     51         @Override
     52         public void onTextChanged(CharSequence s, int start, int before, int count) {
     53           setQueryString(s.toString());
     54         }
     55 
     56         @Override
     57         public void afterTextChanged(Editable s) {}
     58       };
     59   private final SearchEditTextLayout.Callback mSearchLayoutCallback =
     60       new SearchEditTextLayout.Callback() {
     61         @Override
     62         public void onBackButtonClicked() {
     63           getActivity().onBackPressed();
     64         }
     65 
     66         @Override
     67         public void onSearchViewClicked() {}
     68       };
     69   private FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler;
     70   private EditText mSearchView;
     71 
     72   @Override
     73   public void onCreate(Bundle savedInstanceState) {
     74     super.onCreate(savedInstanceState);
     75 
     76     setShowEmptyListForNullQuery(true);
     77     /*
     78      * Pass in the empty string here so ContactEntryListFragment#setQueryString interprets it as
     79      * an empty search query, rather than as an uninitalized value. In the latter case, the
     80      * adapter returned by #createListAdapter is used, which populates the view with contacts.
     81      * Passing in the empty string forces ContactEntryListFragment to interpret it as an empty
     82      * query, which results in showing an empty view
     83      */
     84     setQueryString(getQueryString() == null ? "" : getQueryString());
     85     mFilteredNumberAsyncQueryHandler = new FilteredNumberAsyncQueryHandler(getContext());
     86   }
     87 
     88   @Override
     89   public void onResume() {
     90     super.onResume();
     91 
     92     ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
     93     actionBar.setCustomView(R.layout.search_edittext);
     94     actionBar.setDisplayShowCustomEnabled(true);
     95     actionBar.setDisplayHomeAsUpEnabled(false);
     96     actionBar.setDisplayShowHomeEnabled(false);
     97 
     98     final SearchEditTextLayout searchEditTextLayout =
     99         (SearchEditTextLayout) actionBar.getCustomView().findViewById(R.id.search_view_container);
    100     searchEditTextLayout.expand(false, true);
    101     searchEditTextLayout.setCallback(mSearchLayoutCallback);
    102     searchEditTextLayout.setBackgroundDrawable(null);
    103 
    104     mSearchView = (EditText) searchEditTextLayout.findViewById(R.id.search_view);
    105     mSearchView.addTextChangedListener(mPhoneSearchQueryTextListener);
    106     mSearchView.setHint(R.string.block_number_search_hint);
    107 
    108     searchEditTextLayout
    109         .findViewById(R.id.search_box_expanded)
    110         .setBackgroundColor(getContext().getResources().getColor(android.R.color.white));
    111 
    112     if (!TextUtils.isEmpty(getQueryString())) {
    113       mSearchView.setText(getQueryString());
    114     }
    115 
    116     // TODO: Don't set custom text size; use default search text size.
    117     mSearchView.setTextSize(
    118         TypedValue.COMPLEX_UNIT_PX,
    119         getResources().getDimension(R.dimen.blocked_number_search_text_size));
    120   }
    121 
    122   @Override
    123   protected ContactEntryListAdapter createListAdapter() {
    124     BlockedListSearchAdapter adapter = new BlockedListSearchAdapter(getActivity());
    125     adapter.setDisplayPhotos(true);
    126     // Don't show SIP addresses.
    127     adapter.setUseCallableUri(false);
    128     // Keep in sync with the queryString set in #onCreate
    129     adapter.setQueryString(getQueryString() == null ? "" : getQueryString());
    130     return adapter;
    131   }
    132 
    133   @Override
    134   public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    135     super.onItemClick(parent, view, position, id);
    136     final int adapterPosition = position - getListView().getHeaderViewsCount();
    137     final BlockedListSearchAdapter adapter = (BlockedListSearchAdapter) getAdapter();
    138     final int shortcutType = adapter.getShortcutTypeFromPosition(adapterPosition);
    139     final Integer blockId = (Integer) view.getTag(R.id.block_id);
    140     final String number;
    141     switch (shortcutType) {
    142       case DialerPhoneNumberListAdapter.SHORTCUT_INVALID:
    143         // Handles click on a search result, either contact or nearby places result.
    144         number = adapter.getPhoneNumber(adapterPosition);
    145         blockContactNumber(number, blockId);
    146         break;
    147       case DialerPhoneNumberListAdapter.SHORTCUT_BLOCK_NUMBER:
    148         // Handles click on 'Block number' shortcut to add the user query as a number.
    149         number = adapter.getQueryString();
    150         blockNumber(number);
    151         break;
    152       default:
    153         LogUtil.w(
    154             "BlockedListSearchFragment.onItemClick",
    155             "ignoring unsupported shortcut type: " + shortcutType);
    156         break;
    157     }
    158   }
    159 
    160   @Override
    161   protected void onItemClick(int position, long id) {
    162     // Prevent SearchFragment.onItemClicked from being called.
    163   }
    164 
    165   private void blockNumber(final String number) {
    166     final String countryIso = GeoUtil.getCurrentCountryIso(getContext());
    167     final OnCheckBlockedListener onCheckListener =
    168         new OnCheckBlockedListener() {
    169           @Override
    170           public void onCheckComplete(Integer id) {
    171             if (id == null) {
    172               BlockNumberDialogFragment.show(
    173                   id,
    174                   number,
    175                   countryIso,
    176                   PhoneNumberUtils.formatNumber(number, countryIso),
    177                   R.id.blocked_numbers_activity_container,
    178                   getFragmentManager(),
    179                   BlockedListSearchFragment.this);
    180             } else if (id == FilteredNumberAsyncQueryHandler.INVALID_ID) {
    181               Toast.makeText(
    182                       getContext(),
    183                       ContactDisplayUtils.getTtsSpannedPhoneNumber(
    184                           getResources(), R.string.invalidNumber, number),
    185                       Toast.LENGTH_SHORT)
    186                   .show();
    187             } else {
    188               Toast.makeText(
    189                       getContext(),
    190                       ContactDisplayUtils.getTtsSpannedPhoneNumber(
    191                           getResources(), R.string.alreadyBlocked, number),
    192                       Toast.LENGTH_SHORT)
    193                   .show();
    194             }
    195           }
    196         };
    197     mFilteredNumberAsyncQueryHandler.isBlockedNumber(onCheckListener, number, countryIso);
    198   }
    199 
    200   @Override
    201   public void onFilterNumberSuccess() {
    202     Logger.get(getContext()).logInteraction(InteractionEvent.Type.BLOCK_NUMBER_MANAGEMENT_SCREEN);
    203     goBack();
    204   }
    205 
    206   @Override
    207   public void onUnfilterNumberSuccess() {
    208     LogUtil.e(
    209         "BlockedListSearchFragment.onUnfilterNumberSuccess",
    210         "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(
    230               getContext(),
    231               ContactDisplayUtils.getTtsSpannedPhoneNumber(
    232                   getResources(), R.string.alreadyBlocked, number),
    233               Toast.LENGTH_SHORT)
    234           .show();
    235       return;
    236     }
    237 
    238     BlockNumberDialogFragment.show(
    239         blockId,
    240         number,
    241         GeoUtil.getCurrentCountryIso(getContext()),
    242         number,
    243         R.id.blocked_numbers_activity_container,
    244         getFragmentManager(),
    245         this);
    246   }
    247 }
    248