1032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov/*
2032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov * Copyright (C) 2008 The Android Open Source Project
3032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov *
4032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License");
5032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov * you may not use this file except in compliance with the License.
6032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov * You may obtain a copy of the License at
7032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov *
8032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov *      http://www.apache.org/licenses/LICENSE-2.0
9032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov *
10032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov * Unless required by applicable law or agreed to in writing, software
11032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS,
12032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov * See the License for the specific language governing permissions and
14032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov * limitations under the License.
15032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov */
16032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
1709fba0a6d82a7f88ce3c8cbb74eddd4bb96eb7e4Daniel Lehmannpackage com.android.contacts.activities;
18032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
1909fba0a6d82a7f88ce3c8cbb74eddd4bb96eb7e4Daniel Lehmannimport com.android.contacts.R;
20c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmannimport com.android.contacts.calllog.CallLogFragment;
21c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmannimport com.android.contacts.dialpad.DialpadFragment;
22aae838c5a7ef38f4f2778cff6dfaa1f650a44522Daniel Lehmannimport com.android.contacts.interactions.PhoneNumberInteraction;
238f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawaimport com.android.contacts.list.ContactListFilterController;
248f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawaimport com.android.contacts.list.ContactListFilterController.ContactListFilterListener;
255db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawaimport com.android.contacts.list.ContactListItemView;
26b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawaimport com.android.contacts.list.OnPhoneNumberPickerActionListener;
279b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawaimport com.android.contacts.list.PhoneFavoriteFragment;
28b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawaimport com.android.contacts.list.PhoneNumberPickerFragment;
2918e2b6f48045eebd802ff560420e1ad19b2e2da8Katherine Kuanimport com.android.contacts.activities.TransactionSafeActivity;
3034b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawaimport com.android.contacts.util.AccountFilterUtil;
31b25c13ec8b060cc74f91285929c4535adf4260f0Jeff Hamiltonimport com.android.internal.telephony.ITelephony;
32b25c13ec8b060cc74f91285929c4535adf4260f0Jeff Hamilton
33c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmannimport android.app.ActionBar;
34b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawaimport android.app.ActionBar.LayoutParams;
35c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmannimport android.app.ActionBar.Tab;
36c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmannimport android.app.ActionBar.TabListener;
37032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikovimport android.app.Activity;
38c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmannimport android.app.Fragment;
39c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmannimport android.app.FragmentManager;
40c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmannimport android.app.FragmentTransaction;
41c5be9585f664a893392486e3f86c67f3e083f271Amith Yamasaniimport android.content.Context;
42032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikovimport android.content.Intent;
43903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamiltonimport android.content.SharedPreferences;
44032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikovimport android.net.Uri;
45032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikovimport android.os.Bundle;
46032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikovimport android.os.RemoteException;
47032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikovimport android.os.ServiceManager;
489ed91a9539b6f685b63784cdc84ac41ad14fd988Makoto Onukiimport android.preference.PreferenceManager;
49032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikovimport android.provider.CallLog.Calls;
5018f5f79fa3991a864a17596fe14a04045a7540ebDaisuke Miyakawaimport android.provider.ContactsContract.Contacts;
51b25c13ec8b060cc74f91285929c4535adf4260f0Jeff Hamiltonimport android.provider.ContactsContract.Intents.UI;
52438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawaimport android.support.v13.app.FragmentPagerAdapter;
53438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawaimport android.support.v4.view.ViewPager;
54438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawaimport android.support.v4.view.ViewPager.OnPageChangeListener;
55b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawaimport android.text.TextUtils;
56032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikovimport android.util.Log;
57c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmannimport android.view.Menu;
58c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmannimport android.view.MenuInflater;
59c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmannimport android.view.MenuItem;
60aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawaimport android.view.MenuItem.OnMenuItemClickListener;
61b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawaimport android.view.View;
62ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawaimport android.view.View.OnClickListener;
636beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawaimport android.view.View.OnFocusChangeListener;
6433a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawaimport android.view.ViewConfiguration;
65c5be9585f664a893392486e3f86c67f3e083f271Amith Yamasaniimport android.view.inputmethod.InputMethodManager;
66ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawaimport android.widget.PopupMenu;
67b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawaimport android.widget.SearchView;
68b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawaimport android.widget.SearchView.OnCloseListener;
69b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawaimport android.widget.SearchView.OnQueryTextListener;
70032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
71032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov/**
7208832404d96360ac386a98fd977e45fde936ec30Nicolas Catania * The dialer activity that has one tab with the virtual 12key
7308832404d96360ac386a98fd977e45fde936ec30Nicolas Catania * dialer, a tab with recent calls in it, a tab with the contacts and
7408832404d96360ac386a98fd977e45fde936ec30Nicolas Catania * a tab with the favorite. This is the container and the tabs are
7508832404d96360ac386a98fd977e45fde936ec30Nicolas Catania * embedded using intents.
7608832404d96360ac386a98fd977e45fde936ec30Nicolas Catania * The dialer tab's title is 'phone', a more common name (see strings.xml).
77032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov */
7818e2b6f48045eebd802ff560420e1ad19b2e2da8Katherine Kuanpublic class DialtactsActivity extends TransactionSafeActivity {
7909fba0a6d82a7f88ce3c8cbb74eddd4bb96eb7e4Daniel Lehmann    private static final String TAG = "DialtactsActivity";
807675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann
8143105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa    /** Used to open Call Setting */
8243105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa    private static final String PHONE_PACKAGE = "com.android.phone";
8343105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa    private static final String CALL_SETTINGS_CLASS_NAME =
8443105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            "com.android.phone.CallFeaturesSetting";
8543105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa
86f4fbfdd4f283d2143b87bc6319cb13527b4fe8d1Daisuke Miyakawa    /**
8717c62974608af9b34908c4a14194d53fd89cca6fDaisuke Miyakawa     * Copied from PhoneApp. See comments in Phone app for more detail.
8817c62974608af9b34908c4a14194d53fd89cca6fDaisuke Miyakawa     */
8917c62974608af9b34908c4a14194d53fd89cca6fDaisuke Miyakawa    public static final String EXTRA_CALL_ORIGIN = "com.android.phone.CALL_ORIGIN";
9017c62974608af9b34908c4a14194d53fd89cca6fDaisuke Miyakawa    public static final String CALL_ORIGIN_DIALTACTS =
9117c62974608af9b34908c4a14194d53fd89cca6fDaisuke Miyakawa            "com.android.contacts.activities.DialtactsActivity";
9217c62974608af9b34908c4a14194d53fd89cca6fDaisuke Miyakawa
9317c62974608af9b34908c4a14194d53fd89cca6fDaisuke Miyakawa    /**
94f4fbfdd4f283d2143b87bc6319cb13527b4fe8d1Daisuke Miyakawa     * Just for backward compatibility. Should behave as same as {@link Intent#ACTION_DIAL}.
95f4fbfdd4f283d2143b87bc6319cb13527b4fe8d1Daisuke Miyakawa     */
96f4fbfdd4f283d2143b87bc6319cb13527b4fe8d1Daisuke Miyakawa    private static final String ACTION_TOUCH_DIALER = "com.android.phone.action.TOUCH_DIALER";
97f4fbfdd4f283d2143b87bc6319cb13527b4fe8d1Daisuke Miyakawa
98438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa    /** Used both by {@link ActionBar} and {@link ViewPagerAdapter} */
99032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    private static final int TAB_INDEX_DIALER = 0;
100032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    private static final int TAB_INDEX_CALL_LOG = 1;
10120962611bd54c64c206351d53b51686081d89e53Daisuke Miyakawa    private static final int TAB_INDEX_FAVORITES = 2;
10220962611bd54c64c206351d53b51686081d89e53Daisuke Miyakawa
10320962611bd54c64c206351d53b51686081d89e53Daisuke Miyakawa    private static final int TAB_INDEX_COUNT = 3;
10408832404d96360ac386a98fd977e45fde936ec30Nicolas Catania
1059ed91a9539b6f685b63784cdc84ac41ad14fd988Makoto Onuki    private SharedPreferences mPrefs;
106903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton
1077675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann    /** Last manually selected tab index */
1089ed91a9539b6f685b63784cdc84ac41ad14fd988Makoto Onuki    private static final String PREF_LAST_MANUALLY_SELECTED_TAB =
1099ed91a9539b6f685b63784cdc84ac41ad14fd988Makoto Onuki            "DialtactsActivity_last_manually_selected_tab";
1107675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann    private static final int PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT = TAB_INDEX_DIALER;
1117675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann
11234b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa    private static final int SUBACTIVITY_ACCOUNT_FILTER = 1;
11334b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa
114438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa    /**
115438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa     * Listener interface for Fragments accommodated in {@link ViewPager} enabling them to know
116438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa     * when it becomes visible or invisible inside the ViewPager.
117438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa     */
118438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa    public interface ViewPagerVisibilityListener {
119aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa        public void onVisibilityChanged(boolean visible);
120438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa    }
121438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa
122438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa    public class ViewPagerAdapter extends FragmentPagerAdapter {
123438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        public ViewPagerAdapter(FragmentManager fm) {
124438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa            super(fm);
125438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        }
126438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa
127438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        @Override
128438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        public Fragment getItem(int position) {
129438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa            switch (position) {
130438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa                case TAB_INDEX_DIALER:
131d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki                    return new DialpadFragment();
132438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa                case TAB_INDEX_CALL_LOG:
133d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki                    return new CallLogFragment();
134438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa                case TAB_INDEX_FAVORITES:
135d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki                    return new PhoneFavoriteFragment();
136438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa            }
137438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa            throw new IllegalStateException("No fragment at position " + position);
138438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        }
139438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa
140438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        @Override
141438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        public int getCount() {
142438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa            return TAB_INDEX_COUNT;
143438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        }
144438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa    }
145438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa
146438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa    private class PageChangeListener implements OnPageChangeListener {
147f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa        private int mCurrentPosition = -1;
148f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa        /**
149f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa         * Used during page migration, to remember the next position {@link #onPageSelected(int)}
150f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa         * specified.
151f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa         */
152f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa        private int mNextPosition = -1;
153aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa
154438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        @Override
155438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        public void onPageScrolled(
156438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa                int position, float positionOffset, int positionOffsetPixels) {
157438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        }
158438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa
159438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        @Override
160438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        public void onPageSelected(int position) {
161438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa            final ActionBar actionBar = getActionBar();
162f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa            if (mCurrentPosition == position) {
163aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa                Log.w(TAG, "Previous position and next position became same (" + position + ")");
164aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa            }
165aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa
166438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa            actionBar.selectTab(actionBar.getTabAt(position));
167f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa            mNextPosition = position;
168438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        }
169438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa
17043105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        public void setCurrentPosition(int position) {
171f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa            mCurrentPosition = position;
17243105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        }
17343105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa
174438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        @Override
175438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        public void onPageScrollStateChanged(int state) {
176f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa            switch (state) {
177f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                case ViewPager.SCROLL_STATE_IDLE: {
178f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                    if (mCurrentPosition >= 0) {
179f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                        sendFragmentVisibilityChange(mCurrentPosition, false);
180f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                    }
181f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                    if (mNextPosition >= 0) {
182f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                        sendFragmentVisibilityChange(mNextPosition, true);
183f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                    }
184f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                    invalidateOptionsMenu();
185f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa
186f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                    mCurrentPosition = mNextPosition;
187f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                    break;
188f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                }
189f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                case ViewPager.SCROLL_STATE_DRAGGING:
190f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                case ViewPager.SCROLL_STATE_SETTLING:
191f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                default:
192f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa                    break;
193f6828029b127f60d758bf30052989d64f50cfa86Daisuke Miyakawa            }
194438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        }
195438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa    }
196438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa
19708832404d96360ac386a98fd977e45fde936ec30Nicolas Catania    private String mFilterText;
198438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa
199438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa    /** Enables horizontal swipe between Fragments. */
200438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa    private ViewPager mViewPager;
20143105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa    private final PageChangeListener mPageChangeListener = new PageChangeListener();
202c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann    private DialpadFragment mDialpadFragment;
203c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann    private CallLogFragment mCallLogFragment;
2049b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa    private PhoneFavoriteFragment mPhoneFavoriteFragment;
205032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
206a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa    private final ContactListFilterListener mContactListFilterListener =
207a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa            new ContactListFilterListener() {
208a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa        @Override
209a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa        public void onContactListFilterChanged() {
210a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa            boolean doInvalidateOptionsMenu = false;
211a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa
212a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa            if (mPhoneFavoriteFragment != null && mPhoneFavoriteFragment.isAdded()) {
213a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa                mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter());
214a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa                doInvalidateOptionsMenu = true;
215a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa            }
216a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa
217a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa            if (mSearchFragment != null && mSearchFragment.isAdded()) {
218a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa                mSearchFragment.setFilter(mContactListFilterController.getFilter());
219a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa                doInvalidateOptionsMenu = true;
220a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa            } else {
221a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa                Log.w(TAG, "Search Fragment isn't available when ContactListFilter is changed");
222a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa            }
223a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa
224a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa            if (doInvalidateOptionsMenu) {
225a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa                invalidateOptionsMenu();
226a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa            }
227a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa        }
228a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa    };
229a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa
2302c1f7878d72184a56e9c2b0d9f4d74be439979c2Daisuke Miyakawa    private final TabListener mTabListener = new TabListener() {
23143105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        @Override
23243105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
23343105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        }
23443105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa
23543105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        @Override
23643105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        public void onTabSelected(Tab tab, FragmentTransaction ft) {
23743105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            if (mViewPager.getCurrentItem() != tab.getPosition()) {
2386a3515380fb0658c7e07c3569054646b8473fa3eDaisuke Miyakawa                mViewPager.setCurrentItem(tab.getPosition(), true);
23943105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            }
24043105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa
24143105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            // During the call, we don't remember the tab position.
24243105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            if (!DialpadFragment.phoneIsInUse()) {
24343105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa                // Remember this tab index. This function is also called, if the tab is set
24443105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa                // automatically in which case the setter (setCurrentTab) has to set this to its old
24543105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa                // value afterwards
24643105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa                mLastManuallySelectedFragment = tab.getPosition();
24743105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            }
24843105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        }
24943105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa
25043105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        @Override
25143105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        public void onTabReselected(Tab tab, FragmentTransaction ft) {
25243105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        }
25343105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa    };
25443105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa
2557675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann    /**
256b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * Fragment for searching phone numbers. Unlike the other Fragments, this doesn't correspond
257b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * to tab but is shown by a search action.
258b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     */
259aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa    private PhoneNumberPickerFragment mSearchFragment;
260b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    /**
261b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * True when this Activity is in its search UI (with a {@link SearchView} and
262b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * {@link PhoneNumberPickerFragment}).
263b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     */
264b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    private boolean mInSearchUi;
265aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa    private SearchView mSearchView;
266b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
267ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa    private final OnClickListener mFilterOptionClickListener = new OnClickListener() {
268ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa        @Override
269ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa        public void onClick(View view) {
270ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa            final PopupMenu popupMenu = new PopupMenu(DialtactsActivity.this, view);
271ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa            final Menu menu = popupMenu.getMenu();
272ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa            popupMenu.inflate(R.menu.dialtacts_search_options);
273ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa            final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
274ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa            filterOptionMenuItem.setOnMenuItemClickListener(mFilterOptionsMenuItemClickListener);
27518f5f79fa3991a864a17596fe14a04045a7540ebDaisuke Miyakawa            final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
27618f5f79fa3991a864a17596fe14a04045a7540ebDaisuke Miyakawa            addContactOptionMenuItem.setIntent(
27718f5f79fa3991a864a17596fe14a04045a7540ebDaisuke Miyakawa                    new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
278ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa            popupMenu.show();
279ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa        }
280ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa    };
281ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa
282ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa    /**
283aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa     * The index of the Fragment (or, the tab) that has last been manually selected.
284cfcd0764a1ec53c6014df9ce3e7d3a3da511599fDaisuke Miyakawa     * This value does not keep track of programmatically set Tabs (e.g. Call Log after a Call)
285cfcd0764a1ec53c6014df9ce3e7d3a3da511599fDaisuke Miyakawa     */
286aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa    private int mLastManuallySelectedFragment;
287cfcd0764a1ec53c6014df9ce3e7d3a3da511599fDaisuke Miyakawa
2888f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa    private ContactListFilterController mContactListFilterController;
2898f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa    private OnMenuItemClickListener mFilterOptionsMenuItemClickListener =
2908f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa            new OnMenuItemClickListener() {
2918f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        @Override
2928f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        public boolean onMenuItemClick(MenuItem item) {
29334b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa            AccountFilterUtil.startAccountFilterActivityForResult(
29434b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa                    DialtactsActivity.this, SUBACTIVITY_ACCOUNT_FILTER);
2958f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa            return true;
2968f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        }
2978f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa    };
2988f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa
2998f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa    private OnMenuItemClickListener mSearchMenuItemClickListener =
3008f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa            new OnMenuItemClickListener() {
3018f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        @Override
3028f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        public boolean onMenuItemClick(MenuItem item) {
3038f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa            enterSearchUi();
3048f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa            return true;
3058f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        }
3068f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa    };
3078f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa
308cfcd0764a1ec53c6014df9ce3e7d3a3da511599fDaisuke Miyakawa    /**
309b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * Listener used when one of phone numbers in search UI is selected. This will initiate a
310b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * phone call using the phone number.
311b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     */
312b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    private final OnPhoneNumberPickerActionListener mPhoneNumberPickerActionListener =
313b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa            new OnPhoneNumberPickerActionListener() {
314b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                @Override
315b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                public void onPickPhoneNumberAction(Uri dataUri) {
3167e8372e5fe33ff7252c79b7de7d55b4885074c8cDaisuke Miyakawa                    // Specify call-origin so that users will see the previous tab instead of
3177e8372e5fe33ff7252c79b7de7d55b4885074c8cDaisuke Miyakawa                    // CallLog screen (search UI will be automatically exited).
318b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                    PhoneNumberInteraction.startInteractionForPhoneCall(
3197e8372e5fe33ff7252c79b7de7d55b4885074c8cDaisuke Miyakawa                            DialtactsActivity.this, dataUri,
3207e8372e5fe33ff7252c79b7de7d55b4885074c8cDaisuke Miyakawa                            CALL_ORIGIN_DIALTACTS);
321b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                }
322b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
323b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                @Override
324b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                public void onShortcutIntentCreated(Intent intent) {
325b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                    Log.w(TAG, "Unsupported intent has come (" + intent + "). Ignoring.");
326b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                }
32788f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa
32888f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa                @Override
32988f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa                public void onHomeInActionBarSelected() {
33088f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa                    exitSearchUi();
33188f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa                }
332b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    };
333b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
334b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    /**
335b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * Listener used to send search queries to the phone search fragment.
336b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     */
337b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    private final OnQueryTextListener mPhoneSearchQueryTextListener =
338b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa            new OnQueryTextListener() {
339b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                @Override
340b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                public boolean onQueryTextSubmit(String query) {
341d04768a41fc0c1918eec625fb61e3c8b90719b13Daisuke Miyakawa                    View view = getCurrentFocus();
342d04768a41fc0c1918eec625fb61e3c8b90719b13Daisuke Miyakawa                    if (view != null) {
343d04768a41fc0c1918eec625fb61e3c8b90719b13Daisuke Miyakawa                        hideInputMethod(view);
344d04768a41fc0c1918eec625fb61e3c8b90719b13Daisuke Miyakawa                        view.clearFocus();
345d04768a41fc0c1918eec625fb61e3c8b90719b13Daisuke Miyakawa                    }
346b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                    return true;
347b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                }
348b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
349b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                @Override
350b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                public boolean onQueryTextChange(String newText) {
351b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                    // Show search result with non-empty text. Show a bare list otherwise.
352d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki                    if (mSearchFragment != null) {
353d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki                        mSearchFragment.setQueryString(newText, true);
354d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki                    }
355b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                    return true;
356b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                }
357b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    };
358b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
359b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    /**
360b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * Listener used to handle the "close" button on the right side of {@link SearchView}.
361b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * If some text is in the search view, this will clean it up. Otherwise this will exit
362b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * the search UI and let users go back to usual Phone UI.
363b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     *
364b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * This does _not_ handle back button.
365b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     */
366b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    private final OnCloseListener mPhoneSearchCloseListener =
367b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa            new OnCloseListener() {
368b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                @Override
369b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                public boolean onClose() {
370d04768a41fc0c1918eec625fb61e3c8b90719b13Daisuke Miyakawa                    if (!TextUtils.isEmpty(mSearchView.getQuery())) {
371b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                        mSearchView.setQuery(null, true);
372b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                    }
373b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                    return true;
374b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa                }
375b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    };
376b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
377d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki    private final View.OnLayoutChangeListener mFirstLayoutListener
378d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            = new View.OnLayoutChangeListener() {
379d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        @Override
380d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
381d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki                int oldTop, int oldRight, int oldBottom) {
382d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            v.removeOnLayoutChangeListener(this); // Unregister self.
383d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            addSearchFragment();
384d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        }
385d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki    };
386d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki
387032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    @Override
388032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    protected void onCreate(Bundle icicle) {
389032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        super.onCreate(icicle);
390032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
391032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        final Intent intent = getIntent();
392032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        fixIntent(intent);
39308832404d96360ac386a98fd977e45fde936ec30Nicolas Catania
39409fba0a6d82a7f88ce3c8cbb74eddd4bb96eb7e4Daniel Lehmann        setContentView(R.layout.dialtacts_activity);
395032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
396a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa        mContactListFilterController = ContactListFilterController.getInstance(this);
397a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa        mContactListFilterController.addListener(mContactListFilterListener);
3988f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa
399d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        findViewById(R.id.dialtacts_frame).addOnLayoutChangeListener(mFirstLayoutListener);
400d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki
401438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        mViewPager = (ViewPager) findViewById(R.id.pager);
402438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        mViewPager.setAdapter(new ViewPagerAdapter(getFragmentManager()));
40343105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        mViewPager.setOnPageChangeListener(mPageChangeListener);
404c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann
405c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        // Setup the ActionBar tabs (the order matches the tab-index contants TAB_INDEX_*)
406c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        setupDialer();
407c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        setupCallLog();
408c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        setupFavorites();
409c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
410c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        getActionBar().setDisplayShowTitleEnabled(false);
411c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        getActionBar().setDisplayShowHomeEnabled(false);
412032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
4137675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann        // Load the last manually loaded tab
4149ed91a9539b6f685b63784cdc84ac41ad14fd988Makoto Onuki        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
4159ed91a9539b6f685b63784cdc84ac41ad14fd988Makoto Onuki        mLastManuallySelectedFragment = mPrefs.getInt(PREF_LAST_MANUALLY_SELECTED_TAB,
4167675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann                PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT);
417aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa        if (mLastManuallySelectedFragment >= TAB_INDEX_COUNT) {
41820962611bd54c64c206351d53b51686081d89e53Daisuke Miyakawa            // Stored value may have exceeded the number of current tabs. Reset it.
419aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa            mLastManuallySelectedFragment = PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT;
42020962611bd54c64c206351d53b51686081d89e53Daisuke Miyakawa        }
4217675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann
422032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        setCurrentTab(intent);
423903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton
4247fa3cd652fdaa5284fdf5fa9c306f2ca89227c1aJeff Hamilton        if (UI.FILTER_CONTACTS_ACTION.equals(intent.getAction())
425903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton                && icicle == null) {
426903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton            setupFilterText(intent);
427903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton        }
428032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    }
429032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
430cbe05df145b800118f3ca45f61ea486fad1cca08Daisuke Miyakawa    @Override
431cbe05df145b800118f3ca45f61ea486fad1cca08Daisuke Miyakawa    public void onStart() {
432cbe05df145b800118f3ca45f61ea486fad1cca08Daisuke Miyakawa        super.onStart();
4339b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa        if (mPhoneFavoriteFragment != null) {
4349b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa            mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter());
4359b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa        }
436cbe05df145b800118f3ca45f61ea486fad1cca08Daisuke Miyakawa        if (mSearchFragment != null) {
437cbe05df145b800118f3ca45f61ea486fad1cca08Daisuke Miyakawa            mSearchFragment.setFilter(mContactListFilterController.getFilter());
438cbe05df145b800118f3ca45f61ea486fad1cca08Daisuke Miyakawa        }
439cbe05df145b800118f3ca45f61ea486fad1cca08Daisuke Miyakawa    }
440cbe05df145b800118f3ca45f61ea486fad1cca08Daisuke Miyakawa
441a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa    @Override
442a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa    public void onDestroy() {
443a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa        super.onDestroy();
444a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa        mContactListFilterController.removeListener(mContactListFilterListener);
445a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa    }
446a012aec6f22dd6a37c518c895db45b173e186ef4Daisuke Miyakawa
447d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki    /**
448d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki     * Add search fragment.  Note this is called during onLayout, so there's some restrictions,
449d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki     * such as executePendingTransaction can't be used in it.
450d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki     */
451d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki    private void addSearchFragment() {
452d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        // In order to take full advantage of "fragment deferred start", we need to create the
453d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        // search fragment after all other fragments are created.
454d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        // The other fragments are created by the ViewPager on the first onMeasure().
455d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        // We use the first onLayout call, which is after onMeasure().
456d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki
457d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        // Just return if the fragment is already created, which happens after configuration
458d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        // changes.
459d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        if (mSearchFragment != null) return;
460d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki
461d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        final FragmentTransaction ft = getFragmentManager().beginTransaction();
462d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        final Fragment searchFragment = new PhoneNumberPickerFragment();
463d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki
464d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        searchFragment.setUserVisibleHint(false);
465d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        ft.add(R.id.dialtacts_frame, searchFragment);
466d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        ft.hide(searchFragment);
467d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        ft.commitAllowingStateLoss();
468d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki    }
469d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki
470f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa    private void prepareSearchView() {
471f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        final View searchViewLayout =
472ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa                getLayoutInflater().inflate(R.layout.dialtacts_custom_action_bar, null);
473f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        mSearchView = (SearchView) searchViewLayout.findViewById(R.id.search_view);
474f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        mSearchView.setOnQueryTextListener(mPhoneSearchQueryTextListener);
475f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        mSearchView.setOnCloseListener(mPhoneSearchCloseListener);
476f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        // Since we're using a custom layout for showing SearchView instead of letting the
477f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        // search menu icon do that job, we need to manually configure the View so it looks
478f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        // "shown via search menu".
479f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        // - it should be iconified by default
480f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        // - it should not be iconified at this time
481f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        // See also comments for onActionViewExpanded()/onActionViewCollapsed()
482f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        mSearchView.setIconifiedByDefault(true);
483f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        mSearchView.setQueryHint(getString(R.string.hint_findContacts));
484f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        mSearchView.setIconified(false);
4856beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa        mSearchView.setOnQueryTextFocusChangeListener(new OnFocusChangeListener() {
4866beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa            @Override
4876beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa            public void onFocusChange(View view, boolean hasFocus) {
4886beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa                if (hasFocus) {
4896beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa                    showInputMethod(view.findFocus());
4906beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa                }
4916beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa            }
4926beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa        });
493ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa
494ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa        if (!ViewConfiguration.get(this).hasPermanentMenuKey()) {
495ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa            // Filter option menu should be shown on the right side of SearchView.
496b59500deb3a7cb7c681b1196ba9ccb57e4e2d83eDaisuke Miyakawa            final View filterOptionView = searchViewLayout.findViewById(R.id.search_option);
497b59500deb3a7cb7c681b1196ba9ccb57e4e2d83eDaisuke Miyakawa            filterOptionView.setVisibility(View.VISIBLE);
498b59500deb3a7cb7c681b1196ba9ccb57e4e2d83eDaisuke Miyakawa            filterOptionView.setOnClickListener(mFilterOptionClickListener);
499ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa        }
500ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa
501f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        getActionBar().setCustomView(searchViewLayout,
502f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
503f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa    }
504f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa
505903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton    @Override
50643105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa    public void onAttachFragment(Fragment fragment) {
50743105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        // This method can be called before onCreate(), at which point we cannot rely on ViewPager.
50843105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        // In that case, we will setup the "current position" soon after the ViewPager is ready.
50943105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        final int currentPosition = mViewPager != null ? mViewPager.getCurrentItem() : -1;
51043105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa
51143105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        if (fragment instanceof DialpadFragment) {
51243105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            mDialpadFragment = (DialpadFragment) fragment;
51343105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            mDialpadFragment.setListener(mDialpadListener);
514c36c75318f8e47679d5281b7de2a2b5295eede50Flavio Lerda            if (currentPosition == TAB_INDEX_DIALER) {
515c36c75318f8e47679d5281b7de2a2b5295eede50Flavio Lerda                mDialpadFragment.onVisibilityChanged(true);
516c36c75318f8e47679d5281b7de2a2b5295eede50Flavio Lerda            }
51743105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        } else if (fragment instanceof CallLogFragment) {
51843105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            mCallLogFragment = (CallLogFragment) fragment;
519c36c75318f8e47679d5281b7de2a2b5295eede50Flavio Lerda            if (currentPosition == TAB_INDEX_CALL_LOG) {
520c36c75318f8e47679d5281b7de2a2b5295eede50Flavio Lerda                mCallLogFragment.onVisibilityChanged(true);
521c36c75318f8e47679d5281b7de2a2b5295eede50Flavio Lerda            }
5229b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa        } else if (fragment instanceof PhoneFavoriteFragment) {
5239b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa            mPhoneFavoriteFragment = (PhoneFavoriteFragment) fragment;
5249b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa            mPhoneFavoriteFragment.setListener(mPhoneFavoriteListener);
5259b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa            if (mContactListFilterController != null
5269b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa                    && mContactListFilterController.getFilter() != null) {
5279b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa                mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter());
5289b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa            }
52943105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        } else if (fragment instanceof PhoneNumberPickerFragment) {
53043105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            mSearchFragment = (PhoneNumberPickerFragment) fragment;
53143105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            mSearchFragment.setOnPhoneNumberPickerActionListener(mPhoneNumberPickerActionListener);
53243105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            mSearchFragment.setQuickContactEnabled(true);
533ecfc26c3f9495f1a4efed69a1582ff2b0deb2c71Daniel Lehmann            mSearchFragment.setDarkTheme(true);
5345db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa            mSearchFragment.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
535d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            if (mContactListFilterController != null
536d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki                    && mContactListFilterController.getFilter() != null) {
537d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki                mSearchFragment.setFilter(mContactListFilterController.getFilter());
538d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            }
539d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // Here we assume that we're not on the search mode, so let's hide the fragment.
540d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            //
541d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // We get here either when the fragment is created (normal case), or after configuration
542d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // changes.  In the former case, we're not in search mode because we can only
543d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // enter search mode if the fragment is created.  (see enterSearchUi())
544d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // In the latter case we're not in search mode either because we don't retain
545d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // mInSearchUi -- ideally we should but at this point it's not supported.
5469bd59f27cc5ad318b4bb78fc0576604e57f0b7a6Adam Powell            mSearchFragment.setUserVisibleHint(false);
547d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // After configuration changes fragments will forget their "hidden" state, so make
548d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // sure to hide it.
549d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            if (!mSearchFragment.isHidden()) {
550d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki                final FragmentTransaction transaction = getFragmentManager().beginTransaction();
55143105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa                transaction.hide(mSearchFragment);
552d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki                transaction.commitAllowingStateLoss();
55343105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            }
55443105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        }
55543105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa    }
55643105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa
55743105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa    @Override
558903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton    protected void onPause() {
559903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton        super.onPause();
56008832404d96360ac386a98fd977e45fde936ec30Nicolas Catania
5619ed91a9539b6f685b63784cdc84ac41ad14fd988Makoto Onuki        mPrefs.edit().putInt(PREF_LAST_MANUALLY_SELECTED_TAB, mLastManuallySelectedFragment)
5629ed91a9539b6f685b63784cdc84ac41ad14fd988Makoto Onuki                .apply();
563903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton    }
56408832404d96360ac386a98fd977e45fde936ec30Nicolas Catania
565032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    private void fixIntent(Intent intent) {
566032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        // This should be cleaned up: the call key used to send an Intent
567032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        // that just said to go to the recent calls list.  It now sends this
568032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        // abstract action, but this class hasn't been rewritten to deal with it.
569032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        if (Intent.ACTION_CALL_BUTTON.equals(intent.getAction())) {
570032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            intent.setDataAndType(Calls.CONTENT_URI, Calls.CONTENT_TYPE);
571032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            intent.putExtra("call_key", true);
572032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            setIntent(intent);
573032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        }
574032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    }
57508832404d96360ac386a98fd977e45fde936ec30Nicolas Catania
576c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann    private void setupDialer() {
577c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        final Tab tab = getActionBar().newTab();
578d0d5eaae0052140a1e993ec63c930b0309e36e3bDaisuke Miyakawa        tab.setContentDescription(R.string.dialerIconLabel);
57943105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        tab.setTabListener(mTabListener);
580c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        tab.setIcon(R.drawable.ic_tab_dialer);
581c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        getActionBar().addTab(tab);
582032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    }
583032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
584c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann    private void setupCallLog() {
585c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        final Tab tab = getActionBar().newTab();
586d0d5eaae0052140a1e993ec63c930b0309e36e3bDaisuke Miyakawa        tab.setContentDescription(R.string.recentCallsIconLabel);
587c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        tab.setIcon(R.drawable.ic_tab_recent);
58843105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        tab.setTabListener(mTabListener);
589c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        getActionBar().addTab(tab);
590032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    }
591032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
592c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann    private void setupFavorites() {
593c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        final Tab tab = getActionBar().newTab();
594d0d5eaae0052140a1e993ec63c930b0309e36e3bDaisuke Miyakawa        tab.setContentDescription(R.string.contactsFavoritesLabel);
5959679e44ab946e3c822b7a733f1a998a5cbbfc2b5Daisuke Miyakawa        tab.setIcon(R.drawable.ic_tab_all);
59643105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        tab.setTabListener(mTabListener);
597c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        getActionBar().addTab(tab);
5989add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan    }
5999add0e5ef2a267acbe104e04f4cf6ab24cb8ba3eKatherine Kuan
600032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    /**
601032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov     * Returns true if the intent is due to hitting the green send key while in a call.
60208832404d96360ac386a98fd977e45fde936ec30Nicolas Catania     *
603032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov     * @param intent the intent that launched this activity
604032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov     * @param recentCallsRequest true if the intent is requesting to view recent calls
60508832404d96360ac386a98fd977e45fde936ec30Nicolas Catania     * @return true if the intent is due to hitting the green send key while in a call
606032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov     */
607aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa    private boolean isSendKeyWhileInCall(final Intent intent,
608aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa            final boolean recentCallsRequest) {
609032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        // If there is a call in progress go to the call screen
610032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        if (recentCallsRequest) {
611032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            final boolean callKey = intent.getBooleanExtra("call_key", false);
612032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
613032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            try {
614032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov                ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
615032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov                if (callKey && phone != null && phone.showCallScreen()) {
616032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov                    return true;
617032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov                }
618032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            } catch (RemoteException e) {
619032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov                Log.e(TAG, "Failed to handle send while in call", e);
620032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            }
621032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        }
622032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
623032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        return false;
624032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    }
625032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
626032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    /**
627032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov     * Sets the current tab based on the intent's request type
62808832404d96360ac386a98fd977e45fde936ec30Nicolas Catania     *
6297675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann     * @param intent Intent that contains information about which tab should be selected
630032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov     */
631032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    private void setCurrentTab(Intent intent) {
632032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        // If we got here by hitting send and we're in call forward along to the in-call activity
633032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        final boolean recentCallsRequest = Calls.CONTENT_TYPE.equals(intent.getType());
634032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        if (isSendKeyWhileInCall(intent, recentCallsRequest)) {
635032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            finish();
636032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            return;
637032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        }
63808832404d96360ac386a98fd977e45fde936ec30Nicolas Catania
6397675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann        // Remember the old manually selected tab index so that it can be restored if it is
6407675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann        // overwritten by one of the programmatic tab selections
641aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa        final int savedTabIndex = mLastManuallySelectedFragment;
6427675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann
643438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        final int tabIndex;
644438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        if (DialpadFragment.phoneIsInUse() || isDialIntent(intent)) {
645438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa            tabIndex = TAB_INDEX_DIALER;
646c18f9b7cb0846d0c10fe0398224b53530a2194ecDaisuke Miyakawa        } else if (recentCallsRequest) {
647438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa            tabIndex = TAB_INDEX_CALL_LOG;
648903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton        } else {
649aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa            tabIndex = mLastManuallySelectedFragment;
650032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        }
65168ca6aa964ae356354615a3bbc19ea99b4597a4bDaisuke Miyakawa
65268ca6aa964ae356354615a3bbc19ea99b4597a4bDaisuke Miyakawa        final int previousItemIndex = mViewPager.getCurrentItem();
653aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa        mViewPager.setCurrentItem(tabIndex, false /* smoothScroll */);
65468ca6aa964ae356354615a3bbc19ea99b4597a4bDaisuke Miyakawa        if (previousItemIndex != tabIndex) {
65568ca6aa964ae356354615a3bbc19ea99b4597a4bDaisuke Miyakawa            sendFragmentVisibilityChange(previousItemIndex, false);
65643105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        }
65768ca6aa964ae356354615a3bbc19ea99b4597a4bDaisuke Miyakawa        mPageChangeListener.setCurrentPosition(tabIndex);
65868ca6aa964ae356354615a3bbc19ea99b4597a4bDaisuke Miyakawa        sendFragmentVisibilityChange(tabIndex, true);
659032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
6607675e12b55f9492bf0f6062811f2a0ed030dc1cfDaniel Lehmann        // Restore to the previous manual selection
661aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa        mLastManuallySelectedFragment = savedTabIndex;
662032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    }
663032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
664032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    @Override
665032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    public void onNewIntent(Intent newIntent) {
666032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        setIntent(newIntent);
667032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        fixIntent(newIntent);
668032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        setCurrentTab(newIntent);
669903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton        final String action = newIntent.getAction();
6707fa3cd652fdaa5284fdf5fa9c306f2ca89227c1aJeff Hamilton        if (UI.FILTER_CONTACTS_ACTION.equals(action)) {
671903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton            setupFilterText(newIntent);
672032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        }
673d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        if (mInSearchUi || (mSearchFragment != null && mSearchFragment.isVisible())) {
674438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa            exitSearchUi();
675438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        }
676b15498a22a1b4dae0fc4be681f7b63d1d7dab1ebDaisuke Miyakawa
677b15498a22a1b4dae0fc4be681f7b63d1d7dab1ebDaisuke Miyakawa        if (mViewPager.getCurrentItem() == TAB_INDEX_DIALER) {
678b15498a22a1b4dae0fc4be681f7b63d1d7dab1ebDaisuke Miyakawa            if (mDialpadFragment != null) {
679b15498a22a1b4dae0fc4be681f7b63d1d7dab1ebDaisuke Miyakawa                mDialpadFragment.configureScreenFromIntent(newIntent);
680b15498a22a1b4dae0fc4be681f7b63d1d7dab1ebDaisuke Miyakawa            } else {
681b15498a22a1b4dae0fc4be681f7b63d1d7dab1ebDaisuke Miyakawa                Log.e(TAG, "DialpadFragment isn't ready yet when the tab is already selected.");
682b15498a22a1b4dae0fc4be681f7b63d1d7dab1ebDaisuke Miyakawa            }
683b15498a22a1b4dae0fc4be681f7b63d1d7dab1ebDaisuke Miyakawa        }
684a07abf7f425f2da7487d58851c10c30c03ebda91Daisuke Miyakawa        invalidateOptionsMenu();
685032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    }
686032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
687032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    /** Returns true if the given intent contains a phone number to populate the dialer with */
688032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    private boolean isDialIntent(Intent intent) {
689032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        final String action = intent.getAction();
690f4fbfdd4f283d2143b87bc6319cb13527b4fe8d1Daisuke Miyakawa        if (Intent.ACTION_DIAL.equals(action) || ACTION_TOUCH_DIALER.equals(action)) {
691032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            return true;
692032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        }
693032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        if (Intent.ACTION_VIEW.equals(action)) {
694032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            final Uri data = intent.getData();
695032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            if (data != null && "tel".equals(data.getScheme())) {
696032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov                return true;
697032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            }
698032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        }
699032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        return false;
700032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    }
70108832404d96360ac386a98fd977e45fde936ec30Nicolas Catania
702903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton    /**
703903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton     * Retrieves the filter text stored in {@link #setupFilterText(Intent)}.
704903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton     * This text originally came from a FILTER_CONTACTS_ACTION intent received
705903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton     * by this activity. The stored text will then be cleared after after this
706903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton     * method returns.
70708832404d96360ac386a98fd977e45fde936ec30Nicolas Catania     *
708903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton     * @return The stored filter text
709903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton     */
710903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton    public String getAndClearFilterText() {
711903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton        String filterText = mFilterText;
712903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton        mFilterText = null;
713903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton        return filterText;
714903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton    }
715903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton
716903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton    /**
717903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton     * Stores the filter text associated with a FILTER_CONTACTS_ACTION intent.
718903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton     * This is so child activities can check if they are supposed to display a filter.
71908832404d96360ac386a98fd977e45fde936ec30Nicolas Catania     *
720903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton     * @param intent The intent received in {@link #onNewIntent(Intent)}
721903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton     */
722903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton    private void setupFilterText(Intent intent) {
723903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton        // If the intent was relaunched from history, don't apply the filter text.
724903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton        if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
725903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton            return;
726903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton        }
727b25c13ec8b060cc74f91285929c4535adf4260f0Jeff Hamilton        String filter = intent.getStringExtra(UI.FILTER_TEXT_EXTRA_KEY);
728903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton        if (filter != null && filter.length() > 0) {
729903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton            mFilterText = filter;
730903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton        }
731903137768d56ca85d026c2f4b92e4ace6e068d3bJeff Hamilton    }
732032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
733032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    @Override
734242599a0f1ab23e2a46eff963484a70ec7981befDianne Hackborn    public void onBackPressed() {
735b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        if (mInSearchUi) {
736b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa            // We should let the user go back to usual screens with tabs.
737b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa            exitSearchUi();
738b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        } else if (isTaskRoot()) {
739032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            // Instead of stopping, simply push this to the back of the stack.
740032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            // This is only done when running at the top of the stack;
741032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            // otherwise, we have been launched by someone else so need to
742032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            // allow the user to go back to the caller.
743032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov            moveTaskToBack(false);
744242599a0f1ab23e2a46eff963484a70ec7981befDianne Hackborn        } else {
745242599a0f1ab23e2a46eff963484a70ec7981befDianne Hackborn            super.onBackPressed();
746032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov        }
747032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov    }
748032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov
74943105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa    private DialpadFragment.Listener mDialpadListener = new DialpadFragment.Listener() {
750c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        @Override
75143105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        public void onSearchButtonPressed() {
75243105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            enterSearchUi();
753c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        }
75443105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa    };
755c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann
7569b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa    private PhoneFavoriteFragment.Listener mPhoneFavoriteListener =
7579b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa            new PhoneFavoriteFragment.Listener() {
75832f395567c9d103e9101c2549f76945c9dee20b5Frank Sposaro        @Override
75932f395567c9d103e9101c2549f76945c9dee20b5Frank Sposaro        public void onContactSelected(Uri contactUri) {
760b1f0e5e8a4de69bd80276742900441e930fa4c86Daisuke Miyakawa            PhoneNumberInteraction.startInteractionForPhoneCall(
76117c62974608af9b34908c4a14194d53fd89cca6fDaisuke Miyakawa                    DialtactsActivity.this, contactUri,
76217c62974608af9b34908c4a14194d53fd89cca6fDaisuke Miyakawa                    CALL_ORIGIN_DIALTACTS);
76332f395567c9d103e9101c2549f76945c9dee20b5Frank Sposaro        }
76432f395567c9d103e9101c2549f76945c9dee20b5Frank Sposaro    };
76532f395567c9d103e9101c2549f76945c9dee20b5Frank Sposaro
766c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann    @Override
767c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann    public boolean onCreateOptionsMenu(Menu menu) {
768c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        MenuInflater inflater = getMenuInflater();
769aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa        inflater.inflate(R.menu.dialtacts_options, menu);
770c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        return true;
771c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann    }
772c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann
773c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann    @Override
774aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa    public boolean onPrepareOptionsMenu(Menu menu) {
775aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa        final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
7768f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
77718f5f79fa3991a864a17596fe14a04045a7540ebDaisuke Miyakawa        final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
778231a6fb24a67f054641e7c7d21c487915d35f4acDaisuke Miyakawa        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
7798f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        Tab tab = getActionBar().getSelectedTab();
7808f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        if (mInSearchUi) {
781aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa            searchMenuItem.setVisible(false);
782ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa            if (ViewConfiguration.get(this).hasPermanentMenuKey()) {
783ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa                filterOptionMenuItem.setVisible(true);
784ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa                filterOptionMenuItem.setOnMenuItemClickListener(
785ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa                        mFilterOptionsMenuItemClickListener);
78618f5f79fa3991a864a17596fe14a04045a7540ebDaisuke Miyakawa                addContactOptionMenuItem.setVisible(true);
78718f5f79fa3991a864a17596fe14a04045a7540ebDaisuke Miyakawa                addContactOptionMenuItem.setIntent(
78818f5f79fa3991a864a17596fe14a04045a7540ebDaisuke Miyakawa                        new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
789ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa            } else {
790ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa                // Filter option menu should be not be shown as a overflow menu.
791ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa                filterOptionMenuItem.setVisible(false);
79218f5f79fa3991a864a17596fe14a04045a7540ebDaisuke Miyakawa                addContactOptionMenuItem.setVisible(false);
793ad3e9d878ac1412568151182ebe94c41c2a91d37Daisuke Miyakawa            }
794231a6fb24a67f054641e7c7d21c487915d35f4acDaisuke Miyakawa            callSettingsMenuItem.setVisible(false);
795aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa        } else {
79633a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawa            final boolean showCallSettingsMenu;
797231a6fb24a67f054641e7c7d21c487915d35f4acDaisuke Miyakawa            if (tab != null && tab.getPosition() == TAB_INDEX_DIALER) {
798231a6fb24a67f054641e7c7d21c487915d35f4acDaisuke Miyakawa                searchMenuItem.setVisible(false);
79933a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawa                // When permanent menu key is _not_ available, the call settings menu should be
80033a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawa                // available via DialpadFragment.
80133a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawa                showCallSettingsMenu = ViewConfiguration.get(this).hasPermanentMenuKey();
802231a6fb24a67f054641e7c7d21c487915d35f4acDaisuke Miyakawa            } else {
803231a6fb24a67f054641e7c7d21c487915d35f4acDaisuke Miyakawa                searchMenuItem.setVisible(true);
804231a6fb24a67f054641e7c7d21c487915d35f4acDaisuke Miyakawa                searchMenuItem.setOnMenuItemClickListener(mSearchMenuItemClickListener);
80533a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawa                showCallSettingsMenu = true;
806231a6fb24a67f054641e7c7d21c487915d35f4acDaisuke Miyakawa            }
8079b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa            if (tab != null && tab.getPosition() == TAB_INDEX_FAVORITES) {
8089b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa                filterOptionMenuItem.setVisible(true);
8099b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa                filterOptionMenuItem.setOnMenuItemClickListener(
8109b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa                        mFilterOptionsMenuItemClickListener);
8115db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa                addContactOptionMenuItem.setVisible(true);
8125db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa                addContactOptionMenuItem.setIntent(
8135db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa                        new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
8149b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa            } else {
8159b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa                filterOptionMenuItem.setVisible(false);
8165db4f136163675105813900b1f3f7da48bde97b6Daisuke Miyakawa                addContactOptionMenuItem.setVisible(false);
8179b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa            }
81833a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawa
81933a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawa            if (showCallSettingsMenu) {
82033a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawa                callSettingsMenuItem.setVisible(true);
82133a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawa                callSettingsMenuItem.setIntent(DialtactsActivity.getCallSettingsIntent());
82233a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawa            } else {
82333a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawa                callSettingsMenuItem.setVisible(false);
82433a3023e9071af540fd5fbb32c6d09cf6234fdd1Daisuke Miyakawa            }
825c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann        }
826aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa
827aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa        return true;
828c15062754af08cadc50b4b8ec89c2175a4bec1feDaniel Lehmann    }
829b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
830b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    @Override
831b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    public void startSearch(String initialQuery, boolean selectInitialQuery,
832b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa            Bundle appSearchData, boolean globalSearch) {
83343105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        if (mSearchFragment != null && mSearchFragment.isAdded() && !globalSearch) {
8346beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa            if (mInSearchUi) {
8356beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa                if (mSearchView.hasFocus()) {
8366beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa                    showInputMethod(mSearchView.findFocus());
8376beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa                } else {
8386beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa                    mSearchView.requestFocus();
8396beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa                }
8406beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa            } else {
8416beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa                enterSearchUi();
8426beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa            }
843b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        } else {
844b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa            super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
845b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        }
846b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    }
847b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
848b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    /**
849b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * Hides every tab and shows search UI for phone lookup.
850b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     */
851b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    private void enterSearchUi() {
852d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        if (mSearchFragment == null) {
853d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // We add the search fragment dynamically in the first onLayoutChange() and
854d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // mSearchFragment is set sometime later when the fragment transaction is actually
855d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // executed, which means there's a window when users are able to hit the (physical)
856d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // search key but mSearchFragment is still null.
857d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // It's quite hard to handle this case right, so let's just ignore the search key
858d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            // in this case.  Users can just hit it again and it will work this time.
859d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            return;
860d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        }
8615a30a6d9aec74bf28b389b787ca5809bcb89822dDaisuke Miyakawa        if (mSearchView == null) {
8625a30a6d9aec74bf28b389b787ca5809bcb89822dDaisuke Miyakawa            prepareSearchView();
8635a30a6d9aec74bf28b389b787ca5809bcb89822dDaisuke Miyakawa        }
8645a30a6d9aec74bf28b389b787ca5809bcb89822dDaisuke Miyakawa
865b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        final ActionBar actionBar = getActionBar();
866b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
867b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        final Tab tab = actionBar.getSelectedTab();
868c18f9b7cb0846d0c10fe0398224b53530a2194ecDaisuke Miyakawa
869c18f9b7cb0846d0c10fe0398224b53530a2194ecDaisuke Miyakawa        // User can search during the call, but we don't want to remember the status.
870c18f9b7cb0846d0c10fe0398224b53530a2194ecDaisuke Miyakawa        if (tab != null && !DialpadFragment.phoneIsInUse()) {
871aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa            mLastManuallySelectedFragment = tab.getPosition();
872b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        }
873b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
874f944adbf961e77c6d22767236efa47cecc3a5db2Daisuke Miyakawa        mSearchView.setQuery(null, true);
875b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
876b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        actionBar.setDisplayShowCustomEnabled(true);
877b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
87888f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa        actionBar.setDisplayShowHomeEnabled(true);
87988f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa        actionBar.setDisplayHomeAsUpEnabled(true);
880b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
88143105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        sendFragmentVisibilityChange(mViewPager.getCurrentItem(), false);
88243105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa
883b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        // Show the search fragment and hide everything else.
884d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        mSearchFragment.setUserVisibleHint(true);
885b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        final FragmentTransaction transaction = getFragmentManager().beginTransaction();
886aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa        transaction.show(mSearchFragment);
8874b25da79091157935042d2942a8961ceba92166fMinh Pham        transaction.commitAllowingStateLoss();
888438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        mViewPager.setVisibility(View.GONE);
889b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
890d04768a41fc0c1918eec625fb61e3c8b90719b13Daisuke Miyakawa        // We need to call this and onActionViewCollapsed() manually, since we are using a custom
891d04768a41fc0c1918eec625fb61e3c8b90719b13Daisuke Miyakawa        // layout instead of asking the search menu item to take care of SearchView.
892d04768a41fc0c1918eec625fb61e3c8b90719b13Daisuke Miyakawa        mSearchView.onActionViewExpanded();
893b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        mInSearchUi = true;
894b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    }
895b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
896c5be9585f664a893392486e3f86c67f3e083f271Amith Yamasani    private void showInputMethod(View view) {
897c5be9585f664a893392486e3f86c67f3e083f271Amith Yamasani        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
898c5be9585f664a893392486e3f86c67f3e083f271Amith Yamasani        if (imm != null) {
8996beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa            if (!imm.showSoftInput(view, 0)) {
9006beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa                Log.w(TAG, "Failed to show soft input method.");
9016beadaeb0f159a150f62471a5c5f0b0463e46733Daisuke Miyakawa            }
902c5be9585f664a893392486e3f86c67f3e083f271Amith Yamasani        }
903c5be9585f664a893392486e3f86c67f3e083f271Amith Yamasani    }
904c5be9585f664a893392486e3f86c67f3e083f271Amith Yamasani
90588f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa    private void hideInputMethod(View view) {
90688f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
9073b0c7db46d43dba4782ef9e04a2860fbcf730bafDaisuke Miyakawa        if (imm != null && view != null) {
90888f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
90988f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa        }
91088f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa    }
91188f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa
912b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    /**
913b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * Goes back to usual Phone UI with tags. Previously selected Tag and associated Fragment
914b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     * should be automatically focused again.
915b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa     */
916b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    private void exitSearchUi() {
917b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        final ActionBar actionBar = getActionBar();
918b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
919d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        // Hide the search fragment, if exists.
920d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        if (mSearchFragment != null) {
921d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            mSearchFragment.setUserVisibleHint(false);
922d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki
923d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            final FragmentTransaction transaction = getFragmentManager().beginTransaction();
924d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            transaction.hide(mSearchFragment);
925d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki            transaction.commitAllowingStateLoss();
926d0cf37c2c9c5a1ff888bc3e853f6115467dae5b9Makoto Onuki        }
927a5ed6df7d3702e648075204b790cf15dcd98a6e6Daisuke Miyakawa
928b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        // We want to hide SearchView and show Tabs. Also focus on previously selected one.
929b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        actionBar.setDisplayShowCustomEnabled(false);
93088f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa        actionBar.setDisplayShowHomeEnabled(false);
931b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
932b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa
93343105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        sendFragmentVisibilityChange(mViewPager.getCurrentItem(), true);
93443105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa
935438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa        mViewPager.setVisibility(View.VISIBLE);
936438e1f19279ea058e145c84dbe3ba62cc14df645Daisuke Miyakawa
93788f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa        hideInputMethod(getCurrentFocus());
93888f70fc83cdd119e85d9890b2875faf5c981b47dDaisuke Miyakawa
939350e8d53a135e0bb62308a93dd09777364c08a58Daisuke Miyakawa        // Request to update option menu.
940350e8d53a135e0bb62308a93dd09777364c08a58Daisuke Miyakawa        invalidateOptionsMenu();
941350e8d53a135e0bb62308a93dd09777364c08a58Daisuke Miyakawa
942d04768a41fc0c1918eec625fb61e3c8b90719b13Daisuke Miyakawa        // See comments in onActionViewExpanded()
943d04768a41fc0c1918eec625fb61e3c8b90719b13Daisuke Miyakawa        mSearchView.onActionViewCollapsed();
944b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa        mInSearchUi = false;
945b2e626ad4fedc0fd726f66b9942d1b2f30d9cfefDaisuke Miyakawa    }
946aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa
947aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa    private Fragment getFragmentAt(int position) {
948aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa        switch (position) {
949aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa            case TAB_INDEX_DIALER:
950aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa                return mDialpadFragment;
951aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa            case TAB_INDEX_CALL_LOG:
952aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa                return mCallLogFragment;
953aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa            case TAB_INDEX_FAVORITES:
9549b9104874ec0680ac60cb0527d127fc1c34bdb7eDaisuke Miyakawa                return mPhoneFavoriteFragment;
955aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa            default:
956aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa                throw new IllegalStateException("Unknown fragment index: " + position);
957aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa        }
958aa72f08effc0b2bac7c56dd2fed9bbeae3a6f109Daisuke Miyakawa    }
95943105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa
96043105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa    private void sendFragmentVisibilityChange(int position, boolean visibility) {
96143105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        final Fragment fragment = getFragmentAt(position);
96243105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        if (fragment instanceof ViewPagerVisibilityListener) {
96343105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa            ((ViewPagerVisibilityListener) fragment).onVisibilityChanged(visibility);
96443105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa        }
96543105d0b04963ac96acc1fa7f97278f927f48948Daisuke Miyakawa    }
966bd762dc826d85e5b7db634ef14a0dbb70c42eaabDaisuke Miyakawa
967bd762dc826d85e5b7db634ef14a0dbb70c42eaabDaisuke Miyakawa    /** Returns an Intent to launch Call Settings screen */
968bd762dc826d85e5b7db634ef14a0dbb70c42eaabDaisuke Miyakawa    public static Intent getCallSettingsIntent() {
969bd762dc826d85e5b7db634ef14a0dbb70c42eaabDaisuke Miyakawa        final Intent intent = new Intent(Intent.ACTION_MAIN);
970bd762dc826d85e5b7db634ef14a0dbb70c42eaabDaisuke Miyakawa        intent.setClassName(PHONE_PACKAGE, CALL_SETTINGS_CLASS_NAME);
971147618fa21a2ed187e79aa2eb0414d5f9170310dDaisuke Miyakawa        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
972bd762dc826d85e5b7db634ef14a0dbb70c42eaabDaisuke Miyakawa        return intent;
973bd762dc826d85e5b7db634ef14a0dbb70c42eaabDaisuke Miyakawa    }
9748f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa
9758f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa    @Override
9768f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
9778f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        if (resultCode != Activity.RESULT_OK) {
9788f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa            return;
9798f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        }
9808f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        switch (requestCode) {
98134b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa            case SUBACTIVITY_ACCOUNT_FILTER: {
98234b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa                AccountFilterUtil.handleAccountFilterResult(
98334b901ca7781cf7fdd4f6275ef98ae73c95749c2Daisuke Miyakawa                        mContactListFilterController, resultCode, data);
9848f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa            }
9858f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa            break;
9868f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa        }
9878f59c2b18b73df6af3c808802620839f0a6a61d4Daisuke Miyakawa    }
988032bb36086d55529b59cbd6ea03d2f9b6cfe36afDmitri Plotnikov}
989