blob: 2ba3d260987097786aca597cc829d7ffcd827640 [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
19import android.app.Activity;
20import android.app.TabActivity;
21import android.content.Intent;
Jeff Hamilton90313772009-07-28 10:20:31 -050022import android.content.SharedPreferences;
23import android.graphics.drawable.Drawable;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080024import android.net.Uri;
25import android.os.Bundle;
26import android.os.RemoteException;
27import android.os.ServiceManager;
Jeff Hamilton90313772009-07-28 10:20:31 -050028import android.provider.CallLog;
29import android.provider.Contacts;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080030import android.provider.CallLog.Calls;
Jeff Hamilton90313772009-07-28 10:20:31 -050031import android.provider.Contacts.Intents.UI;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080032import android.util.Log;
33import android.view.KeyEvent;
34import android.view.Window;
35import android.widget.TabHost;
36import com.android.internal.telephony.ITelephony;
37
38/**
39 * The dialer activity that has one tab with the virtual 12key dialer,
40 * and another tab with recent calls in it. This is the container and the tabs
41 * are embedded using intents.
42 */
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
The Android Open Source Project1f620962009-03-09 11:52:14 -070048 private static final int TAB_INDEX_DIALER = 0;
49 private static final int TAB_INDEX_CALL_LOG = 1;
Jeff Hamilton90313772009-07-28 10:20:31 -050050 private static final int TAB_INDEX_CONTACTS = 2;
51 private static final int TAB_INDEX_FAVORITES = 3;
52
The Android Open Source Project1f620962009-03-09 11:52:14 -070053 static final String EXTRA_IGNORE_STATE = "ignore-state";
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080054
Jeff Hamilton90313772009-07-28 10:20:31 -050055 /** Name of the dialtacts shared preferences */
56 static final String PREFS_DIALTACTS = "dialtacts";
57 /** If true, when handling the contacts intent the favorites tab will be shown instead */
58 static final String PREF_FAVORITES_AS_CONTACTS = "favorites_as_contacts";
59 static final boolean PREF_FAVORITES_AS_CONTACTS_DEFAULT = false;
60
The Android Open Source Project1f620962009-03-09 11:52:14 -070061 private TabHost mTabHost;
Jeff Hamilton90313772009-07-28 10:20:31 -050062 private String mFilterText;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080063 private Uri mDialUri;
64
65 @Override
66 protected void onCreate(Bundle icicle) {
67 super.onCreate(icicle);
68
69 final Intent intent = getIntent();
70 fixIntent(intent);
Jeff Hamilton90313772009-07-28 10:20:31 -050071
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080072 requestWindowFeature(Window.FEATURE_NO_TITLE);
73 setContentView(R.layout.dialer_activity);
74
75 mTabHost = getTabHost();
76 mTabHost.setOnTabChangedListener(this);
77
78 // Setup the tabs
79 setupDialerTab();
80 setupCallLogTab();
Jeff Hamilton90313772009-07-28 10:20:31 -050081 setupContactsTab();
82 setupFavoritesTab();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080083
84 setCurrentTab(intent);
Jeff Hamilton90313772009-07-28 10:20:31 -050085
86 if (intent.getAction().equals(Contacts.Intents.UI.FILTER_CONTACTS_ACTION)
87 && icicle == null) {
88 setupFilterText(intent);
89 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080090 }
91
Jeff Hamilton90313772009-07-28 10:20:31 -050092 @Override
93 protected void onPause() {
94 super.onPause();
95
96 int currentTabIndex = mTabHost.getCurrentTab();
97 if (currentTabIndex == TAB_INDEX_CONTACTS || currentTabIndex == TAB_INDEX_FAVORITES) {
98 SharedPreferences.Editor editor = getSharedPreferences(PREFS_DIALTACTS, MODE_PRIVATE)
99 .edit();
100 editor.putBoolean(PREF_FAVORITES_AS_CONTACTS, currentTabIndex == TAB_INDEX_FAVORITES);
101 editor.commit();
102 }
103 }
104
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800105 private void fixIntent(Intent intent) {
106 // This should be cleaned up: the call key used to send an Intent
107 // that just said to go to the recent calls list. It now sends this
108 // abstract action, but this class hasn't been rewritten to deal with it.
109 if (Intent.ACTION_CALL_BUTTON.equals(intent.getAction())) {
110 intent.setDataAndType(Calls.CONTENT_URI, Calls.CONTENT_TYPE);
111 intent.putExtra("call_key", true);
112 setIntent(intent);
113 }
114 }
Jeff Hamilton90313772009-07-28 10:20:31 -0500115
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800116 private void setupCallLogTab() {
The Android Open Source Project1f620962009-03-09 11:52:14 -0700117 // Force the class since overriding tab entries doesn't work
118 Intent intent = new Intent("com.android.phone.action.RECENT_CALLS");
119 intent.setClass(this, RecentCallsListActivity.class);
120
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800121 mTabHost.addTab(mTabHost.newTabSpec("call_log")
122 .setIndicator(getString(R.string.recentCallsIconLabel),
123 getResources().getDrawable(R.drawable.ic_tab_recent))
The Android Open Source Project1f620962009-03-09 11:52:14 -0700124 .setContent(intent));
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800125 }
126
127 private void setupDialerTab() {
The Android Open Source Project1f620962009-03-09 11:52:14 -0700128 Intent intent = new Intent("com.android.phone.action.TOUCH_DIALER");
129 intent.setClass(this, TwelveKeyDialer.class);
130
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800131 mTabHost.addTab(mTabHost.newTabSpec("dialer")
132 .setIndicator(getString(R.string.dialerIconLabel),
133 getResources().getDrawable(R.drawable.ic_tab_dialer))
The Android Open Source Project1f620962009-03-09 11:52:14 -0700134 .setContent(intent));
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800135 }
136
Jeff Hamilton90313772009-07-28 10:20:31 -0500137 private void setupContactsTab() {
138 Intent intent = new Intent(UI.LIST_DEFAULT);
139 intent.setClass(this, ContactsListActivity.class);
140
141 mTabHost.addTab(mTabHost.newTabSpec("contacts")
142 .setIndicator(getText(R.string.contactsIconLabel),
143 getResources().getDrawable(R.drawable.ic_tab_contacts))
144 .setContent(intent));
145 }
146
147 private void setupFavoritesTab() {
148 Intent intent = new Intent(UI.LIST_STREQUENT_ACTION);
149 intent.setClass(this, ContactsListActivity.class);
150
151 mTabHost.addTab(mTabHost.newTabSpec("favorites")
152 .setIndicator(getString(R.string.contactsFavoritesLabel),
153 getResources().getDrawable(R.drawable.ic_tab_starred))
154 .setContent(intent));
155 }
156
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800157 /**
158 * Returns true if the intent is due to hitting the green send key while in a call.
Jeff Hamilton90313772009-07-28 10:20:31 -0500159 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800160 * @param intent the intent that launched this activity
161 * @param recentCallsRequest true if the intent is requesting to view recent calls
Jeff Hamilton90313772009-07-28 10:20:31 -0500162 * @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 -0800163 */
164 private boolean isSendKeyWhileInCall(final Intent intent, final boolean recentCallsRequest) {
165 // If there is a call in progress go to the call screen
166 if (recentCallsRequest) {
167 final boolean callKey = intent.getBooleanExtra("call_key", false);
168
169 try {
170 ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
171 if (callKey && phone != null && phone.showCallScreen()) {
172 return true;
173 }
174 } catch (RemoteException e) {
175 Log.e(TAG, "Failed to handle send while in call", e);
176 }
177 }
178
179 return false;
180 }
181
182 /**
183 * Sets the current tab based on the intent's request type
Jeff Hamilton90313772009-07-28 10:20:31 -0500184 *
The Android Open Source Project1f620962009-03-09 11:52:14 -0700185 * @param recentCallsRequest true is the recent calls tab is desired, false otherwise
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800186 */
187 private void setCurrentTab(Intent intent) {
The Android Open Source Project1f620962009-03-09 11:52:14 -0700188 // 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 -0800189 final boolean recentCallsRequest = Calls.CONTENT_TYPE.equals(intent.getType());
190 if (isSendKeyWhileInCall(intent, recentCallsRequest)) {
191 finish();
192 return;
193 }
Jeff Hamilton90313772009-07-28 10:20:31 -0500194
The Android Open Source Project1f620962009-03-09 11:52:14 -0700195 // Dismiss menu provided by any children activities
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800196 Activity activity = getLocalActivityManager().
197 getActivity(mTabHost.getCurrentTabTag());
198 if (activity != null) {
199 activity.closeOptionsMenu();
200 }
201
The Android Open Source Project1f620962009-03-09 11:52:14 -0700202 // Tell the children activities that they should ignore any possible saved
203 // state and instead reload their state from the parent's intent
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800204 intent.putExtra(EXTRA_IGNORE_STATE, true);
The Android Open Source Project1f620962009-03-09 11:52:14 -0700205
206 // Choose the tab based on the inbound intent
207 String componentName = intent.getComponent().getClassName();
208 if (getClass().getName().equals(componentName)) {
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800209 if (recentCallsRequest) {
The Android Open Source Project1f620962009-03-09 11:52:14 -0700210 mTabHost.setCurrentTab(TAB_INDEX_CALL_LOG);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800211 } else {
The Android Open Source Project1f620962009-03-09 11:52:14 -0700212 mTabHost.setCurrentTab(TAB_INDEX_DIALER);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800213 }
Jeff Hamilton90313772009-07-28 10:20:31 -0500214 } else if (FAVORITES_ENTRY_COMPONENT.equals(componentName)) {
215 mTabHost.setCurrentTab(TAB_INDEX_FAVORITES);
216 } else {
217 SharedPreferences prefs = getSharedPreferences(PREFS_DIALTACTS, MODE_PRIVATE);
218 boolean favoritesAsContacts = prefs.getBoolean(PREF_FAVORITES_AS_CONTACTS,
219 PREF_FAVORITES_AS_CONTACTS_DEFAULT);
220 if (favoritesAsContacts) {
221 mTabHost.setCurrentTab(TAB_INDEX_FAVORITES);
222 } else {
223 mTabHost.setCurrentTab(TAB_INDEX_CONTACTS);
224 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800225 }
The Android Open Source Project1f620962009-03-09 11:52:14 -0700226
227 // Tell the children activities that they should honor their saved states
228 // instead of the state from the parent's intent
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800229 intent.putExtra(EXTRA_IGNORE_STATE, false);
230 }
231
232 @Override
233 public void onNewIntent(Intent newIntent) {
234 setIntent(newIntent);
235 fixIntent(newIntent);
236 setCurrentTab(newIntent);
Jeff Hamilton90313772009-07-28 10:20:31 -0500237 final String action = newIntent.getAction();
238 if (action.equals(Contacts.Intents.UI.FILTER_CONTACTS_ACTION)) {
239 setupFilterText(newIntent);
240 } else if (isDialIntent(newIntent)) {
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800241 setupDialUri(newIntent);
242 }
243 }
The Android Open Source Project1f620962009-03-09 11:52:14 -0700244
245 /** 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 -0800246 private boolean isDialIntent(Intent intent) {
247 final String action = intent.getAction();
248 if (Intent.ACTION_DIAL.equals(action)) {
249 return true;
250 }
251 if (Intent.ACTION_VIEW.equals(action)) {
252 final Uri data = intent.getData();
253 if (data != null && "tel".equals(data.getScheme())) {
254 return true;
255 }
256 }
257 return false;
258 }
Jeff Hamilton90313772009-07-28 10:20:31 -0500259
260 /**
261 * Retrieves the filter text stored in {@link #setupFilterText(Intent)}.
262 * This text originally came from a FILTER_CONTACTS_ACTION intent received
263 * by this activity. The stored text will then be cleared after after this
264 * method returns.
265 *
266 * @return The stored filter text
267 */
268 public String getAndClearFilterText() {
269 String filterText = mFilterText;
270 mFilterText = null;
271 return filterText;
272 }
273
274 /**
275 * Stores the filter text associated with a FILTER_CONTACTS_ACTION intent.
276 * This is so child activities can check if they are supposed to display a filter.
277 *
278 * @param intent The intent received in {@link #onNewIntent(Intent)}
279 */
280 private void setupFilterText(Intent intent) {
281 // If the intent was relaunched from history, don't apply the filter text.
282 if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
283 return;
284 }
285 String filter = intent.getStringExtra(Contacts.Intents.UI.FILTER_TEXT_EXTRA_KEY);
286 if (filter != null && filter.length() > 0) {
287 mFilterText = filter;
288 }
289 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800290
291 /**
292 * Retrieves the uri stored in {@link #setupDialUri(Intent)}. This uri
293 * originally came from a dial intent received by this activity. The stored
294 * uri will then be cleared after after this method returns.
Jeff Hamilton90313772009-07-28 10:20:31 -0500295 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800296 * @return The stored uri
297 */
298 public Uri getAndClearDialUri() {
299 Uri dialUri = mDialUri;
300 mDialUri = null;
301 return dialUri;
302 }
303
304 /**
305 * Stores the uri associated with a dial intent. This is so child activities can
306 * check if they are supposed to display new dial info.
Jeff Hamilton90313772009-07-28 10:20:31 -0500307 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800308 * @param intent The intent received in {@link #onNewIntent(Intent)}
309 */
310 private void setupDialUri(Intent intent) {
311 // If the intent was relaunched from history, don't reapply the intent.
312 if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
313 return;
314 }
315 mDialUri = intent.getData();
316 }
317
318 @Override
Dianne Hackborn242599a2009-09-14 21:33:24 -0700319 public void onBackPressed() {
320 if (isTaskRoot()) {
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800321 // Instead of stopping, simply push this to the back of the stack.
322 // This is only done when running at the top of the stack;
323 // otherwise, we have been launched by someone else so need to
324 // allow the user to go back to the caller.
325 moveTaskToBack(false);
Dianne Hackborn242599a2009-09-14 21:33:24 -0700326 } else {
327 super.onBackPressed();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800328 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800329 }
330
331 /** {@inheritDoc} */
332 public void onTabChanged(String tabId) {
333 // Because we're using Activities as our tab children, we trigger
334 // onWindowFocusChanged() to let them know when they're active. This may
335 // seem to duplicate the purpose of onResume(), but it's needed because
336 // onResume() can't reliably check if a keyguard is active.
337 Activity activity = getLocalActivityManager().getActivity(tabId);
338 if (activity != null) {
339 activity.onWindowFocusChanged(true);
340 }
341 }
342}