blob: f86a78ade245e02392cf26747aceb03c0b267240 [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;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080022import android.net.Uri;
23import android.os.Bundle;
24import android.os.RemoteException;
25import android.os.ServiceManager;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080026import android.provider.CallLog.Calls;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080027import android.util.Log;
28import android.view.KeyEvent;
29import android.view.Window;
30import android.widget.TabHost;
Dmitri Plotnikov032bb362009-05-06 17:05:39 -070031
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080032import com.android.internal.telephony.ITelephony;
33
34/**
35 * The dialer activity that has one tab with the virtual 12key dialer,
36 * and another tab with recent calls in it. This is the container and the tabs
37 * are embedded using intents.
38 */
Dmitri Plotnikov032bb362009-05-06 17:05:39 -070039public class DialerActivity extends TabActivity implements TabHost.OnTabChangeListener {
40 private static final String TAG = "Dialer";
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080041
The Android Open Source Project1f620962009-03-09 11:52:14 -070042 private static final int TAB_INDEX_DIALER = 0;
43 private static final int TAB_INDEX_CALL_LOG = 1;
Dmitri Plotnikov032bb362009-05-06 17:05:39 -070044
The Android Open Source Project1f620962009-03-09 11:52:14 -070045 static final String EXTRA_IGNORE_STATE = "ignore-state";
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080046
The Android Open Source Project1f620962009-03-09 11:52:14 -070047 private TabHost mTabHost;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080048 private Uri mDialUri;
49
50 @Override
51 protected void onCreate(Bundle icicle) {
52 super.onCreate(icicle);
53
54 final Intent intent = getIntent();
55 fixIntent(intent);
Dmitri Plotnikov032bb362009-05-06 17:05:39 -070056
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080057 requestWindowFeature(Window.FEATURE_NO_TITLE);
58 setContentView(R.layout.dialer_activity);
59
60 mTabHost = getTabHost();
61 mTabHost.setOnTabChangedListener(this);
62
63 // Setup the tabs
64 setupDialerTab();
65 setupCallLogTab();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080066
67 setCurrentTab(intent);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080068 }
69
70 private void fixIntent(Intent intent) {
71 // This should be cleaned up: the call key used to send an Intent
72 // that just said to go to the recent calls list. It now sends this
73 // abstract action, but this class hasn't been rewritten to deal with it.
74 if (Intent.ACTION_CALL_BUTTON.equals(intent.getAction())) {
75 intent.setDataAndType(Calls.CONTENT_URI, Calls.CONTENT_TYPE);
76 intent.putExtra("call_key", true);
77 setIntent(intent);
78 }
79 }
Dmitri Plotnikov032bb362009-05-06 17:05:39 -070080
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080081 private void setupCallLogTab() {
The Android Open Source Project1f620962009-03-09 11:52:14 -070082 // Force the class since overriding tab entries doesn't work
83 Intent intent = new Intent("com.android.phone.action.RECENT_CALLS");
84 intent.setClass(this, RecentCallsListActivity.class);
85
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080086 mTabHost.addTab(mTabHost.newTabSpec("call_log")
87 .setIndicator(getString(R.string.recentCallsIconLabel),
88 getResources().getDrawable(R.drawable.ic_tab_recent))
The Android Open Source Project1f620962009-03-09 11:52:14 -070089 .setContent(intent));
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080090 }
91
92 private void setupDialerTab() {
The Android Open Source Project1f620962009-03-09 11:52:14 -070093 Intent intent = new Intent("com.android.phone.action.TOUCH_DIALER");
94 intent.setClass(this, TwelveKeyDialer.class);
95
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080096 mTabHost.addTab(mTabHost.newTabSpec("dialer")
97 .setIndicator(getString(R.string.dialerIconLabel),
98 getResources().getDrawable(R.drawable.ic_tab_dialer))
The Android Open Source Project1f620962009-03-09 11:52:14 -070099 .setContent(intent));
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800100 }
101
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800102 /**
103 * Returns true if the intent is due to hitting the green send key while in a call.
Dmitri Plotnikov032bb362009-05-06 17:05:39 -0700104 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800105 * @param intent the intent that launched this activity
106 * @param recentCallsRequest true if the intent is requesting to view recent calls
Dmitri Plotnikov032bb362009-05-06 17:05:39 -0700107 * @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 -0800108 */
109 private boolean isSendKeyWhileInCall(final Intent intent, final boolean recentCallsRequest) {
110 // If there is a call in progress go to the call screen
111 if (recentCallsRequest) {
112 final boolean callKey = intent.getBooleanExtra("call_key", false);
113
114 try {
115 ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
116 if (callKey && phone != null && phone.showCallScreen()) {
117 return true;
118 }
119 } catch (RemoteException e) {
120 Log.e(TAG, "Failed to handle send while in call", e);
121 }
122 }
123
124 return false;
125 }
126
127 /**
128 * Sets the current tab based on the intent's request type
Dmitri Plotnikov032bb362009-05-06 17:05:39 -0700129 *
The Android Open Source Project1f620962009-03-09 11:52:14 -0700130 * @param recentCallsRequest true is the recent calls tab is desired, false otherwise
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800131 */
132 private void setCurrentTab(Intent intent) {
The Android Open Source Project1f620962009-03-09 11:52:14 -0700133 // 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 -0800134 final boolean recentCallsRequest = Calls.CONTENT_TYPE.equals(intent.getType());
135 if (isSendKeyWhileInCall(intent, recentCallsRequest)) {
136 finish();
137 return;
138 }
Dmitri Plotnikov032bb362009-05-06 17:05:39 -0700139
The Android Open Source Project1f620962009-03-09 11:52:14 -0700140 // Dismiss menu provided by any children activities
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800141 Activity activity = getLocalActivityManager().
142 getActivity(mTabHost.getCurrentTabTag());
143 if (activity != null) {
144 activity.closeOptionsMenu();
145 }
146
The Android Open Source Project1f620962009-03-09 11:52:14 -0700147 // Tell the children activities that they should ignore any possible saved
148 // state and instead reload their state from the parent's intent
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800149 intent.putExtra(EXTRA_IGNORE_STATE, true);
The Android Open Source Project1f620962009-03-09 11:52:14 -0700150
151 // Choose the tab based on the inbound intent
152 String componentName = intent.getComponent().getClassName();
153 if (getClass().getName().equals(componentName)) {
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800154 if (recentCallsRequest) {
The Android Open Source Project1f620962009-03-09 11:52:14 -0700155 mTabHost.setCurrentTab(TAB_INDEX_CALL_LOG);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800156 } else {
The Android Open Source Project1f620962009-03-09 11:52:14 -0700157 mTabHost.setCurrentTab(TAB_INDEX_DIALER);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800158 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800159 }
The Android Open Source Project1f620962009-03-09 11:52:14 -0700160
161 // Tell the children activities that they should honor their saved states
162 // instead of the state from the parent's intent
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800163 intent.putExtra(EXTRA_IGNORE_STATE, false);
164 }
165
166 @Override
167 public void onNewIntent(Intent newIntent) {
168 setIntent(newIntent);
169 fixIntent(newIntent);
170 setCurrentTab(newIntent);
Dmitri Plotnikov032bb362009-05-06 17:05:39 -0700171 if (isDialIntent(newIntent)) {
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800172 setupDialUri(newIntent);
173 }
174 }
The Android Open Source Project1f620962009-03-09 11:52:14 -0700175
176 /** 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 -0800177 private boolean isDialIntent(Intent intent) {
178 final String action = intent.getAction();
179 if (Intent.ACTION_DIAL.equals(action)) {
180 return true;
181 }
182 if (Intent.ACTION_VIEW.equals(action)) {
183 final Uri data = intent.getData();
184 if (data != null && "tel".equals(data.getScheme())) {
185 return true;
186 }
187 }
188 return false;
189 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800190
191 /**
192 * Retrieves the uri stored in {@link #setupDialUri(Intent)}. This uri
193 * originally came from a dial intent received by this activity. The stored
194 * uri will then be cleared after after this method returns.
Dmitri Plotnikov032bb362009-05-06 17:05:39 -0700195 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800196 * @return The stored uri
197 */
198 public Uri getAndClearDialUri() {
199 Uri dialUri = mDialUri;
200 mDialUri = null;
201 return dialUri;
202 }
203
204 /**
205 * Stores the uri associated with a dial intent. This is so child activities can
206 * check if they are supposed to display new dial info.
Dmitri Plotnikov032bb362009-05-06 17:05:39 -0700207 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800208 * @param intent The intent received in {@link #onNewIntent(Intent)}
209 */
210 private void setupDialUri(Intent intent) {
211 // If the intent was relaunched from history, don't reapply the intent.
212 if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
213 return;
214 }
215 mDialUri = intent.getData();
216 }
217
218 @Override
219 public boolean onKeyDown(int keyCode, KeyEvent event) {
220 // Handle BACK
221 if (keyCode == KeyEvent.KEYCODE_BACK && isTaskRoot()) {
222 // Instead of stopping, simply push this to the back of the stack.
223 // This is only done when running at the top of the stack;
224 // otherwise, we have been launched by someone else so need to
225 // allow the user to go back to the caller.
226 moveTaskToBack(false);
227 return true;
228 }
Dmitri Plotnikov032bb362009-05-06 17:05:39 -0700229
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800230 return super.onKeyDown(keyCode, event);
231 }
232
233 /** {@inheritDoc} */
234 public void onTabChanged(String tabId) {
235 // Because we're using Activities as our tab children, we trigger
236 // onWindowFocusChanged() to let them know when they're active. This may
237 // seem to duplicate the purpose of onResume(), but it's needed because
238 // onResume() can't reliably check if a keyguard is active.
239 Activity activity = getLocalActivityManager().getActivity(tabId);
240 if (activity != null) {
241 activity.onWindowFocusChanged(true);
242 }
243 }
244}