blob: 758a3b592789a433f47000cabd52196b26291ffe [file] [log] [blame]
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -08001/*
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
17package com.android.contacts;
18
Jeff Hamiltondf4b1462010-06-28 10:40:26 -050019import com.android.contacts.activities.ContactsFrontDoor;
Jeff Hamiltonb25c13e2009-09-21 09:22:16 -050020import com.android.internal.telephony.ITelephony;
21
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080022import android.app.Activity;
23import android.app.TabActivity;
24import android.content.Intent;
Jeff Hamilton90313772009-07-28 10:20:31 -050025import android.content.SharedPreferences;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080026import android.net.Uri;
27import android.os.Bundle;
28import android.os.RemoteException;
29import android.os.ServiceManager;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080030import android.provider.CallLog.Calls;
Jeff Hamiltonb25c13e2009-09-21 09:22:16 -050031import android.provider.ContactsContract.Intents.UI;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080032import android.util.Log;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080033import android.view.Window;
34import android.widget.TabHost;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080035
36/**
Nicolas Catania08832402009-09-24 09:52:50 -070037 * The dialer activity that has one tab with the virtual 12key
38 * dialer, a tab with recent calls in it, a tab with the contacts and
39 * a tab with the favorite. This is the container and the tabs are
40 * embedded using intents.
41 * The dialer tab's title is 'phone', a more common name (see strings.xml).
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080042 */
Jeff Hamilton90313772009-07-28 10:20:31 -050043public class DialtactsActivity extends TabActivity implements TabHost.OnTabChangeListener {
44 private static final String TAG = "Dailtacts";
45 private static final String FAVORITES_ENTRY_COMPONENT =
46 "com.android.contacts.DialtactsFavoritesEntryActivity";
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080047
Daniel Lehmann7675e122010-04-21 17:31:11 -070048 /** Opens the Contacts app in the state the user has last set it to */
49 private static final String CONTACTS_LAUNCH_ACTIVITY =
50 "com.android.contacts.ContactsLaunchActivity";
51
The Android Open Source Project1f620962009-03-09 11:52:14 -070052 private static final int TAB_INDEX_DIALER = 0;
53 private static final int TAB_INDEX_CALL_LOG = 1;
Jeff Hamilton90313772009-07-28 10:20:31 -050054 private static final int TAB_INDEX_CONTACTS = 2;
55 private static final int TAB_INDEX_FAVORITES = 3;
Nicolas Catania08832402009-09-24 09:52:50 -070056
The Android Open Source Project1f620962009-03-09 11:52:14 -070057 static final String EXTRA_IGNORE_STATE = "ignore-state";
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080058
Jeff Hamilton90313772009-07-28 10:20:31 -050059 /** Name of the dialtacts shared preferences */
60 static final String PREFS_DIALTACTS = "dialtacts";
61 /** If true, when handling the contacts intent the favorites tab will be shown instead */
62 static final String PREF_FAVORITES_AS_CONTACTS = "favorites_as_contacts";
63 static final boolean PREF_FAVORITES_AS_CONTACTS_DEFAULT = false;
64
Daniel Lehmann7675e122010-04-21 17:31:11 -070065 /** Last manually selected tab index */
66 private static final String PREF_LAST_MANUALLY_SELECTED_TAB = "last_manually_selected_tab";
67 private static final int PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT = TAB_INDEX_DIALER;
68
The Android Open Source Project1f620962009-03-09 11:52:14 -070069 private TabHost mTabHost;
Nicolas Catania08832402009-09-24 09:52:50 -070070 private String mFilterText;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080071 private Uri mDialUri;
72
Daniel Lehmann7675e122010-04-21 17:31:11 -070073 /**
74 * The index of the tab that has last been manually selected (the user clicked on a tab).
75 * This value does not keep track of programmatically set Tabs (e.g. Call Log after a Call)
76 */
77 private int mLastManuallySelectedTab;
78
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080079 @Override
80 protected void onCreate(Bundle icicle) {
81 super.onCreate(icicle);
82
83 final Intent intent = getIntent();
84 fixIntent(intent);
Nicolas Catania08832402009-09-24 09:52:50 -070085
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080086 requestWindowFeature(Window.FEATURE_NO_TITLE);
87 setContentView(R.layout.dialer_activity);
88
89 mTabHost = getTabHost();
90 mTabHost.setOnTabChangedListener(this);
91
92 // Setup the tabs
93 setupDialerTab();
94 setupCallLogTab();
Jeff Hamilton90313772009-07-28 10:20:31 -050095 setupContactsTab();
96 setupFavoritesTab();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080097
Daniel Lehmann7675e122010-04-21 17:31:11 -070098 // Load the last manually loaded tab
99 final SharedPreferences prefs = getSharedPreferences(PREFS_DIALTACTS, MODE_PRIVATE);
100 mLastManuallySelectedTab = prefs.getInt(PREF_LAST_MANUALLY_SELECTED_TAB,
101 PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT);
102
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800103 setCurrentTab(intent);
Jeff Hamilton90313772009-07-28 10:20:31 -0500104
Jeff Hamiltonb25c13e2009-09-21 09:22:16 -0500105 if (intent.getAction().equals(UI.FILTER_CONTACTS_ACTION)
Jeff Hamilton90313772009-07-28 10:20:31 -0500106 && icicle == null) {
107 setupFilterText(intent);
108 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800109 }
110
Jeff Hamilton90313772009-07-28 10:20:31 -0500111 @Override
112 protected void onPause() {
113 super.onPause();
Nicolas Catania08832402009-09-24 09:52:50 -0700114
Daniel Lehmann7675e122010-04-21 17:31:11 -0700115 final int currentTabIndex = mTabHost.getCurrentTab();
116 final SharedPreferences.Editor editor =
117 getSharedPreferences(PREFS_DIALTACTS, MODE_PRIVATE).edit();
Jeff Hamilton90313772009-07-28 10:20:31 -0500118 if (currentTabIndex == TAB_INDEX_CONTACTS || currentTabIndex == TAB_INDEX_FAVORITES) {
Jeff Hamilton90313772009-07-28 10:20:31 -0500119 editor.putBoolean(PREF_FAVORITES_AS_CONTACTS, currentTabIndex == TAB_INDEX_FAVORITES);
Jeff Hamilton90313772009-07-28 10:20:31 -0500120 }
Daniel Lehmann7675e122010-04-21 17:31:11 -0700121 editor.putInt(PREF_LAST_MANUALLY_SELECTED_TAB, mLastManuallySelectedTab);
122
123 editor.commit();
Jeff Hamilton90313772009-07-28 10:20:31 -0500124 }
Nicolas Catania08832402009-09-24 09:52:50 -0700125
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800126 private void fixIntent(Intent intent) {
127 // This should be cleaned up: the call key used to send an Intent
128 // that just said to go to the recent calls list. It now sends this
129 // abstract action, but this class hasn't been rewritten to deal with it.
130 if (Intent.ACTION_CALL_BUTTON.equals(intent.getAction())) {
131 intent.setDataAndType(Calls.CONTENT_URI, Calls.CONTENT_TYPE);
132 intent.putExtra("call_key", true);
133 setIntent(intent);
134 }
135 }
Nicolas Catania08832402009-09-24 09:52:50 -0700136
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800137 private void setupCallLogTab() {
The Android Open Source Project1f620962009-03-09 11:52:14 -0700138 // Force the class since overriding tab entries doesn't work
139 Intent intent = new Intent("com.android.phone.action.RECENT_CALLS");
140 intent.setClass(this, RecentCallsListActivity.class);
141
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800142 mTabHost.addTab(mTabHost.newTabSpec("call_log")
143 .setIndicator(getString(R.string.recentCallsIconLabel),
144 getResources().getDrawable(R.drawable.ic_tab_recent))
The Android Open Source Project1f620962009-03-09 11:52:14 -0700145 .setContent(intent));
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800146 }
147
148 private void setupDialerTab() {
The Android Open Source Project1f620962009-03-09 11:52:14 -0700149 Intent intent = new Intent("com.android.phone.action.TOUCH_DIALER");
150 intent.setClass(this, TwelveKeyDialer.class);
151
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800152 mTabHost.addTab(mTabHost.newTabSpec("dialer")
153 .setIndicator(getString(R.string.dialerIconLabel),
154 getResources().getDrawable(R.drawable.ic_tab_dialer))
The Android Open Source Project1f620962009-03-09 11:52:14 -0700155 .setContent(intent));
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800156 }
157
Jeff Hamilton90313772009-07-28 10:20:31 -0500158 private void setupContactsTab() {
159 Intent intent = new Intent(UI.LIST_DEFAULT);
160 intent.setClass(this, ContactsListActivity.class);
161
162 mTabHost.addTab(mTabHost.newTabSpec("contacts")
163 .setIndicator(getText(R.string.contactsIconLabel),
164 getResources().getDrawable(R.drawable.ic_tab_contacts))
165 .setContent(intent));
166 }
167
168 private void setupFavoritesTab() {
169 Intent intent = new Intent(UI.LIST_STREQUENT_ACTION);
170 intent.setClass(this, ContactsListActivity.class);
171
172 mTabHost.addTab(mTabHost.newTabSpec("favorites")
173 .setIndicator(getString(R.string.contactsFavoritesLabel),
174 getResources().getDrawable(R.drawable.ic_tab_starred))
175 .setContent(intent));
176 }
177
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800178 /**
179 * Returns true if the intent is due to hitting the green send key while in a call.
Nicolas Catania08832402009-09-24 09:52:50 -0700180 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800181 * @param intent the intent that launched this activity
182 * @param recentCallsRequest true if the intent is requesting to view recent calls
Nicolas Catania08832402009-09-24 09:52:50 -0700183 * @return true if the intent is due to hitting the green send key while in a call
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800184 */
185 private boolean isSendKeyWhileInCall(final Intent intent, final boolean recentCallsRequest) {
186 // If there is a call in progress go to the call screen
187 if (recentCallsRequest) {
188 final boolean callKey = intent.getBooleanExtra("call_key", false);
189
190 try {
191 ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
192 if (callKey && phone != null && phone.showCallScreen()) {
193 return true;
194 }
195 } catch (RemoteException e) {
196 Log.e(TAG, "Failed to handle send while in call", e);
197 }
198 }
199
200 return false;
201 }
202
203 /**
204 * Sets the current tab based on the intent's request type
Nicolas Catania08832402009-09-24 09:52:50 -0700205 *
Daniel Lehmann7675e122010-04-21 17:31:11 -0700206 * @param intent Intent that contains information about which tab should be selected
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800207 */
208 private void setCurrentTab(Intent intent) {
The Android Open Source Project1f620962009-03-09 11:52:14 -0700209 // If we got here by hitting send and we're in call forward along to the in-call activity
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800210 final boolean recentCallsRequest = Calls.CONTENT_TYPE.equals(intent.getType());
211 if (isSendKeyWhileInCall(intent, recentCallsRequest)) {
212 finish();
213 return;
214 }
Nicolas Catania08832402009-09-24 09:52:50 -0700215
The Android Open Source Project1f620962009-03-09 11:52:14 -0700216 // Dismiss menu provided by any children activities
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800217 Activity activity = getLocalActivityManager().
218 getActivity(mTabHost.getCurrentTabTag());
219 if (activity != null) {
220 activity.closeOptionsMenu();
221 }
222
The Android Open Source Project1f620962009-03-09 11:52:14 -0700223 // Tell the children activities that they should ignore any possible saved
224 // state and instead reload their state from the parent's intent
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800225 intent.putExtra(EXTRA_IGNORE_STATE, true);
The Android Open Source Project1f620962009-03-09 11:52:14 -0700226
Daniel Lehmann7675e122010-04-21 17:31:11 -0700227 // Remember the old manually selected tab index so that it can be restored if it is
228 // overwritten by one of the programmatic tab selections
229 final int savedTabIndex = mLastManuallySelectedTab;
230
The Android Open Source Project1f620962009-03-09 11:52:14 -0700231 // Choose the tab based on the inbound intent
Jeff Hamiltondf4b1462010-06-28 10:40:26 -0500232 if (intent.getBooleanExtra(ContactsFrontDoor.EXTRA_FRONT_DOOR, false)) {
233 // Launched through the contacts front door, set the proper contacts tab
234 setContactsTab();
Jeff Hamilton90313772009-07-28 10:20:31 -0500235 } else {
Jeff Hamiltondf4b1462010-06-28 10:40:26 -0500236 // Not launched through the front door, look at the component to determine the tab
237 String componentName = intent.getComponent().getClassName();
238 if (getClass().getName().equals(componentName)) {
239 if (recentCallsRequest) {
240 mTabHost.setCurrentTab(TAB_INDEX_CALL_LOG);
241 } else {
242 mTabHost.setCurrentTab(TAB_INDEX_DIALER);
243 }
244 } else if (FAVORITES_ENTRY_COMPONENT.equals(componentName)) {
Jeff Hamilton90313772009-07-28 10:20:31 -0500245 mTabHost.setCurrentTab(TAB_INDEX_FAVORITES);
Jeff Hamiltondf4b1462010-06-28 10:40:26 -0500246 } else if (CONTACTS_LAUNCH_ACTIVITY.equals(componentName)) {
247 mTabHost.setCurrentTab(mLastManuallySelectedTab);
Jeff Hamilton90313772009-07-28 10:20:31 -0500248 } else {
Jeff Hamiltondf4b1462010-06-28 10:40:26 -0500249 setContactsTab();
Jeff Hamilton90313772009-07-28 10:20:31 -0500250 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800251 }
The Android Open Source Project1f620962009-03-09 11:52:14 -0700252
Daniel Lehmann7675e122010-04-21 17:31:11 -0700253 // Restore to the previous manual selection
254 mLastManuallySelectedTab = savedTabIndex;
255
The Android Open Source Project1f620962009-03-09 11:52:14 -0700256 // Tell the children activities that they should honor their saved states
257 // instead of the state from the parent's intent
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800258 intent.putExtra(EXTRA_IGNORE_STATE, false);
259 }
260
Jeff Hamiltondf4b1462010-06-28 10:40:26 -0500261 private void setContactsTab() {
262 SharedPreferences prefs = getSharedPreferences(PREFS_DIALTACTS, MODE_PRIVATE);
263 boolean favoritesAsContacts = prefs.getBoolean(PREF_FAVORITES_AS_CONTACTS,
264 PREF_FAVORITES_AS_CONTACTS_DEFAULT);
265 if (favoritesAsContacts) {
266 mTabHost.setCurrentTab(TAB_INDEX_FAVORITES);
267 } else {
268 mTabHost.setCurrentTab(TAB_INDEX_CONTACTS);
269 }
270 }
271
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800272 @Override
273 public void onNewIntent(Intent newIntent) {
274 setIntent(newIntent);
275 fixIntent(newIntent);
276 setCurrentTab(newIntent);
Jeff Hamilton90313772009-07-28 10:20:31 -0500277 final String action = newIntent.getAction();
Jeff Hamiltonb25c13e2009-09-21 09:22:16 -0500278 if (action.equals(UI.FILTER_CONTACTS_ACTION)) {
Jeff Hamilton90313772009-07-28 10:20:31 -0500279 setupFilterText(newIntent);
280 } else if (isDialIntent(newIntent)) {
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800281 setupDialUri(newIntent);
282 }
283 }
The Android Open Source Project1f620962009-03-09 11:52:14 -0700284
285 /** Returns true if the given intent contains a phone number to populate the dialer with */
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800286 private boolean isDialIntent(Intent intent) {
287 final String action = intent.getAction();
288 if (Intent.ACTION_DIAL.equals(action)) {
289 return true;
290 }
291 if (Intent.ACTION_VIEW.equals(action)) {
292 final Uri data = intent.getData();
293 if (data != null && "tel".equals(data.getScheme())) {
294 return true;
295 }
296 }
297 return false;
298 }
Nicolas Catania08832402009-09-24 09:52:50 -0700299
Jeff Hamilton90313772009-07-28 10:20:31 -0500300 /**
301 * Retrieves the filter text stored in {@link #setupFilterText(Intent)}.
302 * This text originally came from a FILTER_CONTACTS_ACTION intent received
303 * by this activity. The stored text will then be cleared after after this
304 * method returns.
Nicolas Catania08832402009-09-24 09:52:50 -0700305 *
Jeff Hamilton90313772009-07-28 10:20:31 -0500306 * @return The stored filter text
307 */
308 public String getAndClearFilterText() {
309 String filterText = mFilterText;
310 mFilterText = null;
311 return filterText;
312 }
313
314 /**
315 * Stores the filter text associated with a FILTER_CONTACTS_ACTION intent.
316 * This is so child activities can check if they are supposed to display a filter.
Nicolas Catania08832402009-09-24 09:52:50 -0700317 *
Jeff Hamilton90313772009-07-28 10:20:31 -0500318 * @param intent The intent received in {@link #onNewIntent(Intent)}
319 */
320 private void setupFilterText(Intent intent) {
321 // If the intent was relaunched from history, don't apply the filter text.
322 if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
323 return;
324 }
Jeff Hamiltonb25c13e2009-09-21 09:22:16 -0500325 String filter = intent.getStringExtra(UI.FILTER_TEXT_EXTRA_KEY);
Jeff Hamilton90313772009-07-28 10:20:31 -0500326 if (filter != null && filter.length() > 0) {
327 mFilterText = filter;
328 }
329 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800330
331 /**
332 * Retrieves the uri stored in {@link #setupDialUri(Intent)}. This uri
333 * originally came from a dial intent received by this activity. The stored
334 * uri will then be cleared after after this method returns.
Nicolas Catania08832402009-09-24 09:52:50 -0700335 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800336 * @return The stored uri
337 */
338 public Uri getAndClearDialUri() {
339 Uri dialUri = mDialUri;
340 mDialUri = null;
341 return dialUri;
342 }
343
344 /**
345 * Stores the uri associated with a dial intent. This is so child activities can
346 * check if they are supposed to display new dial info.
Nicolas Catania08832402009-09-24 09:52:50 -0700347 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800348 * @param intent The intent received in {@link #onNewIntent(Intent)}
349 */
350 private void setupDialUri(Intent intent) {
351 // If the intent was relaunched from history, don't reapply the intent.
352 if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
353 return;
354 }
355 mDialUri = intent.getData();
356 }
357
358 @Override
Dianne Hackborn242599a2009-09-14 21:33:24 -0700359 public void onBackPressed() {
360 if (isTaskRoot()) {
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800361 // Instead of stopping, simply push this to the back of the stack.
362 // This is only done when running at the top of the stack;
363 // otherwise, we have been launched by someone else so need to
364 // allow the user to go back to the caller.
365 moveTaskToBack(false);
Dianne Hackborn242599a2009-09-14 21:33:24 -0700366 } else {
367 super.onBackPressed();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800368 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800369 }
370
371 /** {@inheritDoc} */
372 public void onTabChanged(String tabId) {
373 // Because we're using Activities as our tab children, we trigger
374 // onWindowFocusChanged() to let them know when they're active. This may
375 // seem to duplicate the purpose of onResume(), but it's needed because
376 // onResume() can't reliably check if a keyguard is active.
377 Activity activity = getLocalActivityManager().getActivity(tabId);
378 if (activity != null) {
379 activity.onWindowFocusChanged(true);
380 }
Daniel Lehmann7675e122010-04-21 17:31:11 -0700381
382 // Remember this tab index. This function is also called, if the tab is set automatically
383 // in which case the setter (setCurrentTab) has to set this to its old value afterwards
384 mLastManuallySelectedTab = mTabHost.getCurrentTab();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800385 }
386}