• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.contacts.list;
17 
18 import android.content.Intent;
19 import android.content.Loader;
20 import android.database.Cursor;
21 import android.net.Uri;
22 import android.os.Bundle;
23 import android.text.TextUtils;
24 import android.util.Log;
25 import android.view.LayoutInflater;
26 import android.view.MenuItem;
27 import android.view.View;
28 import android.view.ViewGroup;
29 
30 import com.android.contacts.R;
31 import com.android.contacts.ShortcutIntentBuilder;
32 import com.android.contacts.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
33 
34 /**
35  * Fragment containing a phone number list for picking.
36  */
37 public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactEntryListAdapter>
38         implements OnShortcutIntentCreatedListener, PhoneNumberListAdapter.Listener {
39     private static final String TAG = "PhoneNumberPicker";
40 
41     private static final String KEY_SHORTCUT_ACTION = "shortcutAction";
42 
43     private OnPhoneNumberPickerActionListener mListener;
44     private String mShortcutAction;
45 
46     private ContactListFilter mFilter;
47 
48     private static final String KEY_FILTER = "filter";
49 
50     /** true if the loader has started at least once. */
51     private boolean mLoaderStarted;
52 
53     private boolean mUseCallableUri;
54 
55     private ContactListItemView.PhotoPosition mPhotoPosition =
56             ContactListItemView.getDefaultPhotoPosition(false /* normal/non opposite */);
57 
58     /**
59      * Handles a click on the video call icon for a row in the list.
60      *
61      * @param position The position in the list where the click ocurred.
62      */
63     @Override
onVideoCallIconClicked(int position)64     public void onVideoCallIconClicked(int position) {
65         callNumber(position, true /* isVideoCall */);
66     }
67 
PhoneNumberPickerFragment()68     public PhoneNumberPickerFragment() {
69         setQuickContactEnabled(false);
70         setPhotoLoaderEnabled(true);
71         setSectionHeaderDisplayEnabled(true);
72         setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
73 
74         // Show nothing instead of letting caller Activity show something.
75         setHasOptionsMenu(true);
76     }
77 
setDirectorySearchEnabled(boolean flag)78     public void setDirectorySearchEnabled(boolean flag) {
79         setDirectorySearchMode(flag ? DirectoryListLoader.SEARCH_MODE_DEFAULT
80                 : DirectoryListLoader.SEARCH_MODE_NONE);
81     }
82 
setOnPhoneNumberPickerActionListener(OnPhoneNumberPickerActionListener listener)83     public void setOnPhoneNumberPickerActionListener(OnPhoneNumberPickerActionListener listener) {
84         this.mListener = listener;
85     }
86 
getOnPhoneNumberPickerListener()87     public OnPhoneNumberPickerActionListener getOnPhoneNumberPickerListener() {
88         return mListener;
89     }
90 
91     @Override
onCreateView(LayoutInflater inflater, ViewGroup container)92     protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
93         super.onCreateView(inflater, container);
94 
95         setVisibleScrollbarEnabled(getVisibleScrollbarEnabled());
96     }
97 
getVisibleScrollbarEnabled()98     protected boolean getVisibleScrollbarEnabled() {
99         return true;
100     }
101 
102     @Override
restoreSavedState(Bundle savedState)103     public void restoreSavedState(Bundle savedState) {
104         super.restoreSavedState(savedState);
105 
106         if (savedState == null) {
107             return;
108         }
109 
110         mFilter = savedState.getParcelable(KEY_FILTER);
111         mShortcutAction = savedState.getString(KEY_SHORTCUT_ACTION);
112     }
113 
114     @Override
onSaveInstanceState(Bundle outState)115     public void onSaveInstanceState(Bundle outState) {
116         super.onSaveInstanceState(outState);
117         outState.putParcelable(KEY_FILTER, mFilter);
118         outState.putString(KEY_SHORTCUT_ACTION, mShortcutAction);
119     }
120 
121     @Override
onOptionsItemSelected(MenuItem item)122     public boolean onOptionsItemSelected(MenuItem item) {
123         final int itemId = item.getItemId();
124         if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
125             if (mListener != null) {
126                 mListener.onHomeInActionBarSelected();
127             }
128             return true;
129         }
130         return super.onOptionsItemSelected(item);
131     }
132 
133     /**
134      * @param shortcutAction either {@link Intent#ACTION_CALL} or
135      *            {@link Intent#ACTION_SENDTO} or null.
136      */
setShortcutAction(String shortcutAction)137     public void setShortcutAction(String shortcutAction) {
138         this.mShortcutAction = shortcutAction;
139     }
140 
141     @Override
onItemClick(int position, long id)142     protected void onItemClick(int position, long id) {
143         callNumber(position, false /* isVideoCall */);
144     }
145 
146     /**
147      * Initiates a call to the number at the specified position.
148      *
149      * @param position The position.
150      * @param isVideoCall {@code true} if the call should be initiated as a video call,
151      *      {@code false} otherwise.
152      */
callNumber(int position, boolean isVideoCall)153     private void callNumber(int position, boolean isVideoCall) {
154         final Uri phoneUri = getPhoneUri(position);
155 
156         if (phoneUri != null) {
157             pickPhoneNumber(phoneUri, isVideoCall);
158         } else {
159             final String number = getPhoneNumber(position);
160             if (!TextUtils.isEmpty(number)) {
161                 cacheContactInfo(position);
162                 mListener.onPickPhoneNumber(number, isVideoCall,
163                         getCallInitiationType(true /* isRemoteDirectory */));
164             } else {
165                 Log.w(TAG, "Item at " + position + " was clicked before"
166                         + " adapter is ready. Ignoring");
167             }
168         }
169     }
170 
cacheContactInfo(int position)171     protected void cacheContactInfo(int position) {
172         // Not implemented. Hook for child classes
173     }
174 
getPhoneNumber(int position)175     protected String getPhoneNumber(int position) {
176         final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
177         return adapter.getPhoneNumber(position);
178     }
179 
getPhoneUri(int position)180     protected Uri getPhoneUri(int position) {
181         final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
182         return adapter.getDataUri(position);
183     }
184 
getLookupKey(int position)185     protected String getLookupKey(int position) {
186         final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
187         return adapter.getLookupKey(position);
188     }
189 
190     @Override
startLoading()191     protected void startLoading() {
192         mLoaderStarted = true;
193         super.startLoading();
194     }
195 
196     @Override
onLoadFinished(Loader<Cursor> loader, Cursor data)197     public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
198         super.onLoadFinished(loader, data);
199 
200         // disable scroll bar if there is no data
201         setVisibleScrollbarEnabled(data != null && !data.isClosed() && data.getCount() > 0);
202     }
203 
setUseCallableUri(boolean useCallableUri)204     public void setUseCallableUri(boolean useCallableUri) {
205         mUseCallableUri = useCallableUri;
206     }
207 
usesCallableUri()208     public boolean usesCallableUri() {
209         return mUseCallableUri;
210     }
211 
212     @Override
createListAdapter()213     protected ContactEntryListAdapter createListAdapter() {
214         PhoneNumberListAdapter adapter = new PhoneNumberListAdapter(getActivity());
215         adapter.setDisplayPhotos(true);
216         adapter.setUseCallableUri(mUseCallableUri);
217         return adapter;
218     }
219 
220     @Override
configureAdapter()221     protected void configureAdapter() {
222         super.configureAdapter();
223 
224         final ContactEntryListAdapter adapter = getAdapter();
225         if (adapter == null) {
226             return;
227         }
228 
229         if (!isSearchMode() && mFilter != null) {
230             adapter.setFilter(mFilter);
231         }
232 
233         setPhotoPosition(adapter);
234     }
235 
setPhotoPosition(ContactEntryListAdapter adapter)236     protected void setPhotoPosition(ContactEntryListAdapter adapter) {
237         ((PhoneNumberListAdapter) adapter).setPhotoPosition(mPhotoPosition);
238     }
239 
240     @Override
inflateView(LayoutInflater inflater, ViewGroup container)241     protected View inflateView(LayoutInflater inflater, ViewGroup container) {
242         return inflater.inflate(R.layout.contact_list_content, null);
243     }
244 
pickPhoneNumber(Uri uri, boolean isVideoCall)245     public void pickPhoneNumber(Uri uri, boolean isVideoCall) {
246         if (mShortcutAction == null) {
247             mListener.onPickDataUri(uri, isVideoCall,
248                     getCallInitiationType(false /* isRemoteDirectory */));
249         } else {
250             startPhoneNumberShortcutIntent(uri, isVideoCall);
251         }
252     }
253 
startPhoneNumberShortcutIntent(Uri uri, boolean isVideoCall)254     protected void startPhoneNumberShortcutIntent(Uri uri, boolean isVideoCall) {
255         ShortcutIntentBuilder builder = new ShortcutIntentBuilder(getActivity(), this);
256         builder.createPhoneNumberShortcutIntent(uri, mShortcutAction);
257     }
258 
259     @Override
onShortcutIntentCreated(Uri uri, Intent shortcutIntent)260     public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) {
261         mListener.onShortcutIntentCreated(shortcutIntent);
262     }
263 
264     @Override
onPickerResult(Intent data)265     public void onPickerResult(Intent data) {
266         mListener.onPickDataUri(data.getData(), false /* isVideoCall */,
267                 getCallInitiationType(false /* isRemoteDirectory */));
268     }
269 
setFilter(ContactListFilter filter)270     public void setFilter(ContactListFilter filter) {
271         if ((mFilter == null && filter == null) ||
272                 (mFilter != null && mFilter.equals(filter))) {
273             return;
274         }
275 
276         mFilter = filter;
277         if (mLoaderStarted) {
278             reloadData();
279         }
280     }
281 
setPhotoPosition(ContactListItemView.PhotoPosition photoPosition)282     public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) {
283         mPhotoPosition = photoPosition;
284 
285         final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
286         if (adapter != null) {
287             adapter.setPhotoPosition(photoPosition);
288         }
289     }
290 
291     /**
292      * @param isRemoteDirectory {@code true} if the call was initiated using a contact/phone number
293      *         not in the local contacts database
294      */
getCallInitiationType(boolean isRemoteDirectory)295     protected int getCallInitiationType(boolean isRemoteDirectory) {
296         return OnPhoneNumberPickerActionListener.CALL_INITIATION_UNKNOWN;
297     }
298 }
299