• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 
17 package com.android.contacts;
18 
19 import com.android.internal.telephony.ITelephony;
20 
21 import android.app.Activity;
22 import android.app.TabActivity;
23 import android.content.Intent;
24 import android.content.SharedPreferences;
25 import android.net.Uri;
26 import android.os.Bundle;
27 import android.os.RemoteException;
28 import android.os.ServiceManager;
29 import android.provider.CallLog.Calls;
30 import android.provider.ContactsContract.Intents.UI;
31 import android.util.Log;
32 import android.view.Window;
33 import android.widget.TabHost;
34 
35 /**
36  * The dialer activity that has one tab with the virtual 12key
37  * dialer, a tab with recent calls in it, a tab with the contacts and
38  * a tab with the favorite. This is the container and the tabs are
39  * embedded using intents.
40  * The dialer tab's title is 'phone', a more common name (see strings.xml).
41  */
42 public class DialtactsActivity extends TabActivity implements TabHost.OnTabChangeListener {
43     private static final String TAG = "Dailtacts";
44     private static final String FAVORITES_ENTRY_COMPONENT =
45             "com.android.contacts.DialtactsFavoritesEntryActivity";
46 
47     private static final int TAB_INDEX_DIALER = 0;
48     private static final int TAB_INDEX_CALL_LOG = 1;
49     private static final int TAB_INDEX_CONTACTS = 2;
50     private static final int TAB_INDEX_FAVORITES = 3;
51 
52     static final String EXTRA_IGNORE_STATE = "ignore-state";
53 
54     /** Name of the dialtacts shared preferences */
55     static final String PREFS_DIALTACTS = "dialtacts";
56     /** If true, when handling the contacts intent the favorites tab will be shown instead */
57     static final String PREF_FAVORITES_AS_CONTACTS = "favorites_as_contacts";
58     static final boolean PREF_FAVORITES_AS_CONTACTS_DEFAULT = false;
59 
60     private TabHost mTabHost;
61     private String mFilterText;
62     private Uri mDialUri;
63 
64     @Override
onCreate(Bundle icicle)65     protected void onCreate(Bundle icicle) {
66         super.onCreate(icicle);
67 
68         final Intent intent = getIntent();
69         fixIntent(intent);
70 
71         requestWindowFeature(Window.FEATURE_NO_TITLE);
72         setContentView(R.layout.dialer_activity);
73 
74         mTabHost = getTabHost();
75         mTabHost.setOnTabChangedListener(this);
76 
77         // Setup the tabs
78         setupDialerTab();
79         setupCallLogTab();
80         setupContactsTab();
81         setupFavoritesTab();
82 
83         setCurrentTab(intent);
84 
85         if (intent.getAction().equals(UI.FILTER_CONTACTS_ACTION)
86                 && icicle == null) {
87             setupFilterText(intent);
88         }
89     }
90 
91     @Override
onPause()92     protected void onPause() {
93         super.onPause();
94 
95         int currentTabIndex = mTabHost.getCurrentTab();
96         if (currentTabIndex == TAB_INDEX_CONTACTS || currentTabIndex == TAB_INDEX_FAVORITES) {
97             SharedPreferences.Editor editor = getSharedPreferences(PREFS_DIALTACTS, MODE_PRIVATE)
98                     .edit();
99             editor.putBoolean(PREF_FAVORITES_AS_CONTACTS, currentTabIndex == TAB_INDEX_FAVORITES);
100             editor.commit();
101         }
102     }
103 
fixIntent(Intent intent)104     private void fixIntent(Intent intent) {
105         // This should be cleaned up: the call key used to send an Intent
106         // that just said to go to the recent calls list.  It now sends this
107         // abstract action, but this class hasn't been rewritten to deal with it.
108         if (Intent.ACTION_CALL_BUTTON.equals(intent.getAction())) {
109             intent.setDataAndType(Calls.CONTENT_URI, Calls.CONTENT_TYPE);
110             intent.putExtra("call_key", true);
111             setIntent(intent);
112         }
113     }
114 
setupCallLogTab()115     private void setupCallLogTab() {
116         // Force the class since overriding tab entries doesn't work
117         Intent intent = new Intent("com.android.phone.action.RECENT_CALLS");
118         intent.setClass(this, RecentCallsListActivity.class);
119 
120         mTabHost.addTab(mTabHost.newTabSpec("call_log")
121                 .setIndicator(getString(R.string.recentCallsIconLabel),
122                         getResources().getDrawable(R.drawable.ic_tab_recent))
123                 .setContent(intent));
124     }
125 
setupDialerTab()126     private void setupDialerTab() {
127         Intent intent = new Intent("com.android.phone.action.TOUCH_DIALER");
128         intent.setClass(this, TwelveKeyDialer.class);
129 
130         mTabHost.addTab(mTabHost.newTabSpec("dialer")
131                 .setIndicator(getString(R.string.dialerIconLabel),
132                         getResources().getDrawable(R.drawable.ic_tab_dialer))
133                 .setContent(intent));
134     }
135 
setupContactsTab()136     private void setupContactsTab() {
137         Intent intent = new Intent(UI.LIST_DEFAULT);
138         intent.setClass(this, ContactsListActivity.class);
139 
140         mTabHost.addTab(mTabHost.newTabSpec("contacts")
141                 .setIndicator(getText(R.string.contactsIconLabel),
142                         getResources().getDrawable(R.drawable.ic_tab_contacts))
143                 .setContent(intent));
144     }
145 
setupFavoritesTab()146     private void setupFavoritesTab() {
147         Intent intent = new Intent(UI.LIST_STREQUENT_ACTION);
148         intent.setClass(this, ContactsListActivity.class);
149 
150         mTabHost.addTab(mTabHost.newTabSpec("favorites")
151                 .setIndicator(getString(R.string.contactsFavoritesLabel),
152                         getResources().getDrawable(R.drawable.ic_tab_starred))
153                 .setContent(intent));
154     }
155 
156     /**
157      * Returns true if the intent is due to hitting the green send key while in a call.
158      *
159      * @param intent the intent that launched this activity
160      * @param recentCallsRequest true if the intent is requesting to view recent calls
161      * @return true if the intent is due to hitting the green send key while in a call
162      */
isSendKeyWhileInCall(final Intent intent, final boolean recentCallsRequest)163     private boolean isSendKeyWhileInCall(final Intent intent, final boolean recentCallsRequest) {
164         // If there is a call in progress go to the call screen
165         if (recentCallsRequest) {
166             final boolean callKey = intent.getBooleanExtra("call_key", false);
167 
168             try {
169                 ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
170                 if (callKey && phone != null && phone.showCallScreen()) {
171                     return true;
172                 }
173             } catch (RemoteException e) {
174                 Log.e(TAG, "Failed to handle send while in call", e);
175             }
176         }
177 
178         return false;
179     }
180 
181     /**
182      * Sets the current tab based on the intent's request type
183      *
184      * @param recentCallsRequest true is the recent calls tab is desired, false otherwise
185      */
setCurrentTab(Intent intent)186     private void setCurrentTab(Intent intent) {
187         // If we got here by hitting send and we're in call forward along to the in-call activity
188         final boolean recentCallsRequest = Calls.CONTENT_TYPE.equals(intent.getType());
189         if (isSendKeyWhileInCall(intent, recentCallsRequest)) {
190             finish();
191             return;
192         }
193 
194         // Dismiss menu provided by any children activities
195         Activity activity = getLocalActivityManager().
196                 getActivity(mTabHost.getCurrentTabTag());
197         if (activity != null) {
198             activity.closeOptionsMenu();
199         }
200 
201         // Tell the children activities that they should ignore any possible saved
202         // state and instead reload their state from the parent's intent
203         intent.putExtra(EXTRA_IGNORE_STATE, true);
204 
205         // Choose the tab based on the inbound intent
206         String componentName = intent.getComponent().getClassName();
207         if (getClass().getName().equals(componentName)) {
208             if (recentCallsRequest) {
209                 mTabHost.setCurrentTab(TAB_INDEX_CALL_LOG);
210             } else {
211                 mTabHost.setCurrentTab(TAB_INDEX_DIALER);
212             }
213         } else if (FAVORITES_ENTRY_COMPONENT.equals(componentName)) {
214             mTabHost.setCurrentTab(TAB_INDEX_FAVORITES);
215         } else {
216             SharedPreferences prefs = getSharedPreferences(PREFS_DIALTACTS, MODE_PRIVATE);
217             boolean favoritesAsContacts = prefs.getBoolean(PREF_FAVORITES_AS_CONTACTS,
218                     PREF_FAVORITES_AS_CONTACTS_DEFAULT);
219             if (favoritesAsContacts) {
220                 mTabHost.setCurrentTab(TAB_INDEX_FAVORITES);
221             } else {
222                 mTabHost.setCurrentTab(TAB_INDEX_CONTACTS);
223             }
224         }
225 
226         // Tell the children activities that they should honor their saved states
227         // instead of the state from the parent's intent
228         intent.putExtra(EXTRA_IGNORE_STATE, false);
229     }
230 
231     @Override
onNewIntent(Intent newIntent)232     public void onNewIntent(Intent newIntent) {
233         setIntent(newIntent);
234         fixIntent(newIntent);
235         setCurrentTab(newIntent);
236         final String action = newIntent.getAction();
237         if (action.equals(UI.FILTER_CONTACTS_ACTION)) {
238             setupFilterText(newIntent);
239         } else if (isDialIntent(newIntent)) {
240             setupDialUri(newIntent);
241         }
242     }
243 
244     /** Returns true if the given intent contains a phone number to populate the dialer with */
isDialIntent(Intent intent)245     private boolean isDialIntent(Intent intent) {
246         final String action = intent.getAction();
247         if (Intent.ACTION_DIAL.equals(action)) {
248             return true;
249         }
250         if (Intent.ACTION_VIEW.equals(action)) {
251             final Uri data = intent.getData();
252             if (data != null && "tel".equals(data.getScheme())) {
253                 return true;
254             }
255         }
256         return false;
257     }
258 
259     /**
260      * Retrieves the filter text stored in {@link #setupFilterText(Intent)}.
261      * This text originally came from a FILTER_CONTACTS_ACTION intent received
262      * by this activity. The stored text will then be cleared after after this
263      * method returns.
264      *
265      * @return The stored filter text
266      */
getAndClearFilterText()267     public String getAndClearFilterText() {
268         String filterText = mFilterText;
269         mFilterText = null;
270         return filterText;
271     }
272 
273     /**
274      * Stores the filter text associated with a FILTER_CONTACTS_ACTION intent.
275      * This is so child activities can check if they are supposed to display a filter.
276      *
277      * @param intent The intent received in {@link #onNewIntent(Intent)}
278      */
setupFilterText(Intent intent)279     private void setupFilterText(Intent intent) {
280         // If the intent was relaunched from history, don't apply the filter text.
281         if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
282             return;
283         }
284         String filter = intent.getStringExtra(UI.FILTER_TEXT_EXTRA_KEY);
285         if (filter != null && filter.length() > 0) {
286             mFilterText = filter;
287         }
288     }
289 
290     /**
291      * Retrieves the uri stored in {@link #setupDialUri(Intent)}. This uri
292      * originally came from a dial intent received by this activity. The stored
293      * uri will then be cleared after after this method returns.
294      *
295      * @return The stored uri
296      */
getAndClearDialUri()297     public Uri getAndClearDialUri() {
298         Uri dialUri = mDialUri;
299         mDialUri = null;
300         return dialUri;
301     }
302 
303     /**
304      * Stores the uri associated with a dial intent. This is so child activities can
305      * check if they are supposed to display new dial info.
306      *
307      * @param intent The intent received in {@link #onNewIntent(Intent)}
308      */
setupDialUri(Intent intent)309     private void setupDialUri(Intent intent) {
310         // If the intent was relaunched from history, don't reapply the intent.
311         if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
312             return;
313         }
314         mDialUri = intent.getData();
315     }
316 
317     @Override
onBackPressed()318     public void onBackPressed() {
319         if (isTaskRoot()) {
320             // Instead of stopping, simply push this to the back of the stack.
321             // This is only done when running at the top of the stack;
322             // otherwise, we have been launched by someone else so need to
323             // allow the user to go back to the caller.
324             moveTaskToBack(false);
325         } else {
326             super.onBackPressed();
327         }
328     }
329 
330     /** {@inheritDoc} */
onTabChanged(String tabId)331     public void onTabChanged(String tabId) {
332         // Because we're using Activities as our tab children, we trigger
333         // onWindowFocusChanged() to let them know when they're active.  This may
334         // seem to duplicate the purpose of onResume(), but it's needed because
335         // onResume() can't reliably check if a keyguard is active.
336         Activity activity = getLocalActivityManager().getActivity(tabId);
337         if (activity != null) {
338             activity.onWindowFocusChanged(true);
339         }
340     }
341 }
342