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.filterednumber;
17 
18 import com.google.common.base.MoreObjects;
19 
20 import android.app.ListFragment;
21 import android.app.LoaderManager;
22 import android.content.Context;
23 import android.content.CursorLoader;
24 import android.content.Loader;
25 import android.database.Cursor;
26 import android.graphics.drawable.ColorDrawable;
27 import android.os.Bundle;
28 import android.support.v4.app.ActivityCompat;
29 import android.support.v7.app.ActionBar;
30 import android.support.v7.app.AppCompatActivity;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.ViewGroup;
34 import android.widget.ImageView;
35 import android.widget.TextView;
36 
37 import com.android.contacts.common.lettertiles.LetterTileDrawable;
38 import com.android.contacts.common.testing.NeededForTesting;
39 import com.android.dialer.R;
40 import com.android.dialer.compat.FilteredNumberCompat;
41 import com.android.dialer.database.FilteredNumberContract;
42 import com.android.dialer.filterednumber.BlockedNumbersMigrator.Listener;
43 import com.android.dialer.filterednumber.FilteredNumbersUtil.CheckForSendToVoicemailContactListener;
44 import com.android.dialer.filterednumber.FilteredNumbersUtil.ImportSendToVoicemailContactsListener;
45 import com.android.dialer.voicemail.VisualVoicemailEnabledChecker;
46 
47 public class BlockedNumbersFragment extends ListFragment
48         implements LoaderManager.LoaderCallbacks<Cursor>, View.OnClickListener,
49         VisualVoicemailEnabledChecker.Callback {
50     private static final char ADD_BLOCKED_NUMBER_ICON_LETTER = '+';
51 
52     private BlockedNumbersMigrator blockedNumbersMigratorForTest;
53     protected View migratePromoView;
54     private TextView blockedNumbersText;
55     private TextView footerText;
56     private BlockedNumbersAdapter mAdapter;
57     private VisualVoicemailEnabledChecker mVoicemailEnabledChecker;
58     private View mImportSettings;
59     private View mBlockedNumbersDisabledForEmergency;
60     private View mBlockedNumberListDivider;
61 
62     @Override
getContext()63     public Context getContext() {
64         return getActivity();
65     }
66 
67     @Override
onActivityCreated(Bundle savedInstanceState)68     public void onActivityCreated(Bundle savedInstanceState) {
69         super.onActivityCreated(savedInstanceState);
70 
71         LayoutInflater inflater =
72                 (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
73         getListView().addHeaderView(inflater.inflate(R.layout.blocked_number_header, null));
74         getListView().addFooterView(inflater.inflate(R.layout.blocked_number_footer, null));
75         //replace the icon for add number with LetterTileDrawable(), so it will have identical style
76         ImageView addNumberIcon = (ImageView) getActivity().findViewById(R.id.add_number_icon);
77         LetterTileDrawable drawable = new LetterTileDrawable(getResources());
78         drawable.setLetter(ADD_BLOCKED_NUMBER_ICON_LETTER);
79         drawable.setColor(ActivityCompat.getColor(getActivity(),
80                 R.color.add_blocked_number_icon_color));
81         drawable.setIsCircular(true);
82         addNumberIcon.setImageDrawable(drawable);
83 
84         if (mAdapter == null) {
85             mAdapter = BlockedNumbersAdapter.newBlockedNumbersAdapter(
86                     getContext(), getActivity().getFragmentManager());
87         }
88         setListAdapter(mAdapter);
89 
90         blockedNumbersText = (TextView) getListView().findViewById(R.id.blocked_number_text_view);
91         migratePromoView = getListView().findViewById(R.id.migrate_promo);
92         getListView().findViewById(R.id.migrate_promo_allow_button).setOnClickListener(this);
93         mImportSettings = getListView().findViewById(R.id.import_settings);
94         mBlockedNumbersDisabledForEmergency =
95                 getListView().findViewById(R.id.blocked_numbers_disabled_for_emergency);
96         mBlockedNumberListDivider = getActivity().findViewById(R.id.blocked_number_list_divider);
97         getListView().findViewById(R.id.import_button).setOnClickListener(this);
98         getListView().findViewById(R.id.view_numbers_button).setOnClickListener(this);
99         getListView().findViewById(R.id.add_number_linear_layout).setOnClickListener(this);
100 
101         footerText = (TextView) getActivity().findViewById(
102             R.id.blocked_number_footer_textview);
103         mVoicemailEnabledChecker = new VisualVoicemailEnabledChecker(getContext(),this);
104         mVoicemailEnabledChecker.asyncUpdate();
105         updateActiveVoicemailProvider();
106     }
107 
108     @Override
onDestroy()109     public void onDestroy() {
110         setListAdapter(null);
111         super.onDestroy();
112     }
113 
114     @Override
onCreate(Bundle savedInstanceState)115     public void onCreate(Bundle savedInstanceState) {
116         super.onCreate(savedInstanceState);
117         getLoaderManager().initLoader(0, null, this);
118     }
119 
120     @Override
onResume()121     public void onResume() {
122         super.onResume();
123 
124         ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
125         ColorDrawable backgroundDrawable = new ColorDrawable(
126                 ActivityCompat.getColor(getActivity(), R.color.dialer_theme_color));
127         actionBar.setBackgroundDrawable(backgroundDrawable);
128         actionBar.setDisplayShowCustomEnabled(false);
129         actionBar.setDisplayHomeAsUpEnabled(true);
130         actionBar.setDisplayShowHomeEnabled(true);
131         actionBar.setDisplayShowTitleEnabled(true);
132         actionBar.setTitle(R.string.manage_blocked_numbers_label);
133 
134         // If the device can use the framework blocking solution, users should not be able to add
135         // new blocked numbers from the Blocked Management UI. They will be shown a promo card
136         // asking them to migrate to new blocking instead.
137         if (FilteredNumberCompat.canUseNewFiltering()) {
138             migratePromoView.setVisibility(View.VISIBLE);
139             blockedNumbersText.setVisibility(View.GONE);
140             getListView().findViewById(R.id.add_number_linear_layout).setVisibility(View.GONE);
141             getListView().findViewById(R.id.add_number_linear_layout).setOnClickListener(null);
142             mBlockedNumberListDivider.setVisibility(View.GONE);
143             mImportSettings.setVisibility(View.GONE);
144             getListView().findViewById(R.id.import_button).setOnClickListener(null);
145             getListView().findViewById(R.id.view_numbers_button).setOnClickListener(null);
146             mBlockedNumbersDisabledForEmergency.setVisibility(View.GONE);
147             footerText.setVisibility(View.GONE);
148         } else {
149             FilteredNumbersUtil.checkForSendToVoicemailContact(
150                     getActivity(), new CheckForSendToVoicemailContactListener() {
151                         @Override
152                         public void onComplete(boolean hasSendToVoicemailContact) {
153                             final int visibility =
154                                     hasSendToVoicemailContact ? View.VISIBLE : View.GONE;
155                             mImportSettings.setVisibility(visibility);
156                         }
157                     });
158         }
159 
160         // All views except migrate and the block list are hidden when new filtering is available
161         if (!FilteredNumberCompat.canUseNewFiltering()
162                 && FilteredNumbersUtil.hasRecentEmergencyCall(getContext())) {
163             mBlockedNumbersDisabledForEmergency.setVisibility(View.VISIBLE);
164         } else {
165             mBlockedNumbersDisabledForEmergency.setVisibility(View.GONE);
166         }
167 
168         mVoicemailEnabledChecker.asyncUpdate();
169     }
170 
171     @Override
onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)172     public View onCreateView(
173             LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
174         return inflater.inflate(R.layout.blocked_number_fragment, container, false);
175     }
176 
177     @Override
onCreateLoader(int id, Bundle args)178     public Loader<Cursor> onCreateLoader(int id, Bundle args) {
179         final String[] projection = {
180             FilteredNumberContract.FilteredNumberColumns._ID,
181             FilteredNumberContract.FilteredNumberColumns.COUNTRY_ISO,
182             FilteredNumberContract.FilteredNumberColumns.NUMBER,
183             FilteredNumberContract.FilteredNumberColumns.NORMALIZED_NUMBER
184         };
185         final String selection = FilteredNumberContract.FilteredNumberColumns.TYPE
186                 + "=" + FilteredNumberContract.FilteredNumberTypes.BLOCKED_NUMBER;
187         return new CursorLoader(
188                 getContext(), FilteredNumberContract.FilteredNumber.CONTENT_URI, projection,
189                 selection, null, null);
190     }
191 
192     @Override
onLoadFinished(Loader<Cursor> loader, Cursor data)193     public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
194         mAdapter.swapCursor(data);
195         if (FilteredNumberCompat.canUseNewFiltering() || data.getCount() == 0) {
196             mBlockedNumberListDivider.setVisibility(View.INVISIBLE);
197         } else {
198             mBlockedNumberListDivider.setVisibility(View.VISIBLE);
199         }
200     }
201 
202     @Override
onLoaderReset(Loader<Cursor> loader)203     public void onLoaderReset(Loader<Cursor> loader) {
204         mAdapter.swapCursor(null);
205     }
206 
207     @Override
onClick(final View view)208     public void onClick(final View view) {
209         final BlockedNumbersSettingsActivity activity =
210                 (BlockedNumbersSettingsActivity) getActivity();
211         if (activity == null) {
212             return;
213         }
214 
215         int resId = view.getId();
216         if (resId == R.id.add_number_linear_layout) {
217             activity.showSearchUi();
218         } else if (resId == R.id.view_numbers_button) {
219             activity.showNumbersToImportPreviewUi();
220         } else if (resId == R.id.import_button) {
221             FilteredNumbersUtil.importSendToVoicemailContacts(activity,
222                     new ImportSendToVoicemailContactsListener() {
223                         @Override
224                         public void onImportComplete() {
225                             mImportSettings.setVisibility(View.GONE);
226                         }
227                     });
228         } else if (resId == R.id.migrate_promo_allow_button) {
229             view.setEnabled(false);
230             MoreObjects.firstNonNull(blockedNumbersMigratorForTest,
231                 new BlockedNumbersMigrator(getContext().getContentResolver()))
232                 .migrate(new Listener() {
233                     @Override
234                     public void onComplete() {
235                         getContext().startActivity(
236                             FilteredNumberCompat.createManageBlockedNumbersIntent(getContext()));
237                         // Remove this activity from the backstack
238                         activity.finish();
239                 }
240             });
241         }
242     }
243 
244     @Override
onVisualVoicemailEnabledStatusChanged(boolean newStatus)245     public void onVisualVoicemailEnabledStatusChanged(boolean newStatus){
246         updateActiveVoicemailProvider();
247     }
248 
updateActiveVoicemailProvider()249     private void updateActiveVoicemailProvider(){
250         if (getActivity() == null || getActivity().isFinishing()) {
251             return;
252         }
253         if (mVoicemailEnabledChecker.isVisualVoicemailEnabled()) {
254             footerText.setText(R.string.block_number_footer_message_vvm);
255         } else {
256             footerText.setText(R.string.block_number_footer_message_no_vvm);
257         }
258     }
259 
260     @NeededForTesting
setBlockedNumbersMigratorForTest(BlockedNumbersMigrator blockedNumbersMigrator)261     void setBlockedNumbersMigratorForTest(BlockedNumbersMigrator blockedNumbersMigrator) {
262         blockedNumbersMigratorForTest = blockedNumbersMigrator;
263     }
264 }
265