QuickContactActivity.java revision 0d5588da244d0992c3ff8f25d0875fdf95a8c644
1edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann/* 2edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * Copyright (C) 2009 The Android Open Source Project 3edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * 4edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * Licensed under the Apache License, Version 2.0 (the "License"); 5edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * you may not use this file except in compliance with the License. 6edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * You may obtain a copy of the License at 7edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * 8edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * http://www.apache.org/licenses/LICENSE-2.0 9edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * 10edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * Unless required by applicable law or agreed to in writing, software 11edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * distributed under the License is distributed on an "AS IS" BASIS, 12edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * See the License for the specific language governing permissions and 14edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * limitations under the License. 15edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann */ 16edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 17edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannpackage com.android.contacts.quickcontact; 18edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 19edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.app.Activity; 20edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.app.Fragment; 21edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.app.FragmentManager; 22cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmannimport android.app.LoaderManager.LoaderCallbacks; 23edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.content.ActivityNotFoundException; 24edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.content.ContentUris; 25edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.content.Context; 26edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.content.Intent; 27cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmannimport android.content.Loader; 28edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.content.pm.PackageManager; 29edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.graphics.Rect; 30edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.graphics.drawable.Drawable; 31edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.net.Uri; 32edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.os.Bundle; 33edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.os.Handler; 34edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.Email; 35edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.Phone; 36edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.SipAddress; 37edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 38edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.Website; 39edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.provider.ContactsContract.Contacts; 40edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.provider.ContactsContract.QuickContact; 41edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.provider.ContactsContract.RawContacts; 42edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.support.v13.app.FragmentPagerAdapter; 43edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.support.v4.view.ViewPager; 44edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.support.v4.view.ViewPager.SimpleOnPageChangeListener; 45edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.text.TextUtils; 46edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.util.Log; 47edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.view.MotionEvent; 48edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.view.View; 49edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.view.View.OnClickListener; 50edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.view.ViewGroup; 5110d7df7bab8c332744fad64b9167c2ef061070e4Daisuke Miyakawaimport android.view.WindowManager; 52edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.widget.HorizontalScrollView; 53edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.widget.ImageButton; 54edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.widget.ImageView; 55edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.widget.RelativeLayout; 56edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.widget.TextView; 57edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport android.widget.Toast; 58edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 59d7ca03e23948c3b2d5f97ec5598d8b50e3fc0b25Chiao Chengimport com.android.contacts.common.Collapser; 60e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R; 610d5588da244d0992c3ff8f25d0875fdf95a8c644Chiao Chengimport com.android.contacts.common.model.AccountTypeManager; 62851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.Contact; 63851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.ContactLoader; 64851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContact; 65428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.account.AccountType; 66851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.DataItem; 67428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.dataitem.DataKind; 68851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.EmailDataItem; 69851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.ImDataItem; 70d9eab4da8b9946b76a2091e5cce6c858663ef1bbChiao Chengimport com.android.contacts.common.util.Constants; 71e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.DataStatus; 72e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.ImageViewDrawableSetter; 73e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.SchedulingUtils; 749f2a5e78c9604d9c407f1464c7cb72ec5f2bb04dChiao Chengimport com.android.contacts.common.util.StopWatch; 75e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.google.common.base.Preconditions; 76e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.google.common.collect.Lists; 77e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng 78edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport java.util.HashMap; 79edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport java.util.HashSet; 80edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport java.util.List; 81edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannimport java.util.Set; 82edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 83edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann// TODO: Save selected tab index during rotation 84edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 85edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann/** 86edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * Mostly translucent {@link Activity} that shows QuickContact dialog. It loads 87edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * data asynchronously, and then shows a popup with details centered around 88edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * {@link Intent#getSourceBounds()}. 89edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann */ 90edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmannpublic class QuickContactActivity extends Activity { 91edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private static final String TAG = "QuickContact"; 92edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 93edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private static final boolean TRACE_LAUNCH = false; 94edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private static final String TRACE_TAG = "quickcontact"; 95ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus private static final int POST_DRAW_WAIT_DURATION = 60; 96dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki private static final boolean ENABLE_STOPWATCH = false; 97dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 98edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 99edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @SuppressWarnings("deprecation") 100edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private static final String LEGACY_AUTHORITY = android.provider.Contacts.AUTHORITY; 101edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 102edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private Uri mLookupUri; 103edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private String[] mExcludeMimes; 104edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private List<String> mSortedActionMimeTypes = Lists.newArrayList(); 105edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 106edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private FloatingChildLayout mFloatingLayout; 107edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 108edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private View mPhotoContainer; 109edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private ViewGroup mTrack; 110edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private HorizontalScrollView mTrackScroller; 111edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private View mSelectedTabRectangle; 1121792b08c500ed528e7d21401affd936b3a7b3dc6Daniel Lehmann private View mLineAfterTrack; 113edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 1149d85a2a39a4b9a0bacee8d25b2830784caf8551cYorke Lee private ImageView mOpenDetailsImage; 115edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private ImageButton mOpenDetailsPushLayerButton; 116edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private ViewPager mListPager; 117edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 1189815d7f98baf80ce51b0cf1f01f48a3dbb9a9db9Daniel Lehmann private ContactLoader mContactLoader; 1199815d7f98baf80ce51b0cf1f01f48a3dbb9a9db9Daniel Lehmann 1209758a92fac3e9f64892d893c992f6020d7fe3bfdJosh Gargus private final ImageViewDrawableSetter mPhotoSetter = new ImageViewDrawableSetter(); 1219758a92fac3e9f64892d893c992f6020d7fe3bfdJosh Gargus 122edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann /** 123edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * Keeps the default action per mimetype. Empty if no default actions are set 124edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann */ 125edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private HashMap<String, Action> mDefaultsMap = new HashMap<String, Action>(); 126edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 127edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann /** 128edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * Set of {@link Action} that are associated with the aggregate currently 129edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * displayed by this dialog, represented as a map from {@link String} 130edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * MIME-type to a list of {@link Action}. 131edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann */ 132edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private ActionMultiMap mActions = new ActionMultiMap(); 133edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 134edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann /** 135edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * {@link #LEADING_MIMETYPES} and {@link #TRAILING_MIMETYPES} are used to sort MIME-types. 136edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * 137edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * <p>The MIME-types in {@link #LEADING_MIMETYPES} appear in the front of the dialog, 138edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * in the order specified here.</p> 139edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * 140edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * <p>The ones in {@link #TRAILING_MIMETYPES} appear in the end of the dialog, in the order 141edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * specified here.</p> 142edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * 143edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * <p>The rest go between them, in the order in the array.</p> 144edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann */ 145edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private static final List<String> LEADING_MIMETYPES = Lists.newArrayList( 146edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann Phone.CONTENT_ITEM_TYPE, SipAddress.CONTENT_ITEM_TYPE, Email.CONTENT_ITEM_TYPE); 147edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 148edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann /** See {@link #LEADING_MIMETYPES}. */ 149edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private static final List<String> TRAILING_MIMETYPES = Lists.newArrayList( 150edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann StructuredPostal.CONTENT_ITEM_TYPE, Website.CONTENT_ITEM_TYPE); 151edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 152cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann /** Id for the background loader */ 153cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann private static final int LOADER_ID = 0; 154edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 155dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki private StopWatch mStopWatch = ENABLE_STOPWATCH 156dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki ? StopWatch.start("QuickContact") : StopWatch.getNullStopWatch(); 157dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 158edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 159edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann protected void onCreate(Bundle icicle) { 160dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("c"); // create start 161edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann super.onCreate(icicle); 162edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 163dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("sc"); // super.onCreate 164dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 1652426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann if (TRACE_LAUNCH) android.os.Debug.startMethodTracing(TRACE_TAG); 1662426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann 167dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki // Parse intent 168dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki final Intent intent = getIntent(); 169dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 170dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki Uri lookupUri = intent.getData(); 171dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 172dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki // Check to see whether it comes from the old version. 173dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki if (lookupUri != null && LEGACY_AUTHORITY.equals(lookupUri.getAuthority())) { 174dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki final long rawContactId = ContentUris.parseId(lookupUri); 175dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki lookupUri = RawContacts.getContactLookupUri(getContentResolver(), 176dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId)); 177dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki } 178dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 179dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mLookupUri = Preconditions.checkNotNull(lookupUri, "missing lookupUri"); 180dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 181dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mExcludeMimes = intent.getStringArrayExtra(QuickContact.EXTRA_EXCLUDE_MIMES); 182dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 183dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("i"); // intent parsed 184dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 185dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mContactLoader = (ContactLoader) getLoaderManager().initLoader( 186dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki LOADER_ID, null, mLoaderCallbacks); 187dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 188dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("ld"); // loader started 189dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 19010d7df7bab8c332744fad64b9167c2ef061070e4Daisuke Miyakawa // Show QuickContact in front of soft input 19110d7df7bab8c332744fad64b9167c2ef061070e4Daisuke Miyakawa getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, 19210d7df7bab8c332744fad64b9167c2ef061070e4Daisuke Miyakawa WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 19310d7df7bab8c332744fad64b9167c2ef061070e4Daisuke Miyakawa 194edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann setContentView(R.layout.quickcontact_activity); 195edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 196dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("l"); // layout inflated 197dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 198edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mFloatingLayout = (FloatingChildLayout) findViewById(R.id.floating_layout); 199edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mTrack = (ViewGroup) findViewById(R.id.track); 200edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mTrackScroller = (HorizontalScrollView) findViewById(R.id.track_scroller); 2019d85a2a39a4b9a0bacee8d25b2830784caf8551cYorke Lee mOpenDetailsImage = (ImageView) findViewById(R.id.contact_details_image); 202edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mOpenDetailsPushLayerButton = (ImageButton) findViewById(R.id.open_details_push_layer); 203edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mListPager = (ViewPager) findViewById(R.id.item_list_pager); 204edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mSelectedTabRectangle = findViewById(R.id.selected_tab_rectangle); 2051792b08c500ed528e7d21401affd936b3a7b3dc6Daniel Lehmann mLineAfterTrack = findViewById(R.id.line_after_track); 206edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 207edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mFloatingLayout.setOnOutsideTouchListener(new View.OnTouchListener() { 208edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 209edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public boolean onTouch(View v, MotionEvent event) { 2102426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann handleOutsideTouch(); 2112426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann return true; 212edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 213edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann }); 214edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 215edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final OnClickListener openDetailsClickHandler = new OnClickListener() { 216edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 217edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public void onClick(View v) { 218edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final Intent intent = new Intent(Intent.ACTION_VIEW, mLookupUri); 2199815d7f98baf80ce51b0cf1f01f48a3dbb9a9db9Daniel Lehmann mContactLoader.cacheResult(); 2208ca93ed0938e00ee94b03e6d609895593cfdbdbdAdam Powell intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 221edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann startActivity(intent); 2222426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann close(false); 223edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 224edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann }; 225edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mOpenDetailsPushLayerButton.setOnClickListener(openDetailsClickHandler); 226edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mListPager.setAdapter(new ViewPagerAdapter(getFragmentManager())); 227edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mListPager.setOnPageChangeListener(new PageChangeListener()); 228edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 229d1e501105d1ce2fb3e286635d0b2195e77e000afDaniel Lehmann final Rect sourceBounds = intent.getSourceBounds(); 230802fa62aac8edc92be136b8227ccafa53cd774fbMakoto Onuki if (sourceBounds != null) { 231802fa62aac8edc92be136b8227ccafa53cd774fbMakoto Onuki mFloatingLayout.setChildTargetScreen(sourceBounds); 232802fa62aac8edc92be136b8227ccafa53cd774fbMakoto Onuki } 233edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 234edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // find and prepare correct header view 235edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mPhotoContainer = findViewById(R.id.photo_container); 23681281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan setHeaderNameText(R.id.name, R.string.missing_name); 237edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 238dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("v"); // view initialized 239edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 2403a53c73f04eef94b311bb0469c1d0ca7059c0411Daniel Lehmann SchedulingUtils.doAfterLayout(mFloatingLayout, new Runnable() { 2413a53c73f04eef94b311bb0469c1d0ca7059c0411Daniel Lehmann @Override 2423a53c73f04eef94b311bb0469c1d0ca7059c0411Daniel Lehmann public void run() { 2433a53c73f04eef94b311bb0469c1d0ca7059c0411Daniel Lehmann mFloatingLayout.fadeInBackground(); 2443a53c73f04eef94b311bb0469c1d0ca7059c0411Daniel Lehmann } 2453a53c73f04eef94b311bb0469c1d0ca7059c0411Daniel Lehmann }); 246dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 247dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("cf"); // onCreate finished 2482426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann } 249edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 2502426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann private void handleOutsideTouch() { 2512426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann if (mFloatingLayout.isContentFullyVisible()) { 2522426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann close(true); 2532426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann } 254edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 255edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 2562426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann private void close(boolean withAnimation) { 257edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // cancel any pending queries 258cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann getLoaderManager().destroyLoader(LOADER_ID); 259edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 260edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann if (withAnimation) { 2612426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann mFloatingLayout.fadeOutBackground(); 2622426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann final boolean animated = mFloatingLayout.hideContent(new Runnable() { 263edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 264edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public void run() { 265ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus // Wait until the final animation frame has been drawn, otherwise 266ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus // there is jank as the framework transitions to the next Activity. 267ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus SchedulingUtils.doAfterDraw(mFloatingLayout, new Runnable() { 268ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus @Override 269ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus public void run() { 270ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus // Unfortunately, we need to also use postDelayed() to wait a moment 271ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus // for the frame to be drawn, else the framework's activity-transition 272ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus // animation will kick in before the final frame is available to it. 273ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus // This seems unavoidable. The problem isn't merely that there is no 274ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus // post-draw listener API; if that were so, it would be sufficient to 275ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus // call post() instead of postDelayed(). 276ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus new Handler().postDelayed(new Runnable() { 277ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus @Override 278ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus public void run() { 279ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus finish(); 280ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus } 281ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus }, POST_DRAW_WAIT_DURATION); 282ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus } 283ee287e9a7617fc38119a026f7e802f6d7d47113cJosh Gargus }); 284edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 285edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann }); 2862426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann if (!animated) { 2872426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann // If we were in the wrong state, simply quit (this can happen for example 2882426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann // if the user pushes BACK before anything has loaded) 2892426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann finish(); 2902426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann } 291edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } else { 292edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann finish(); 293edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 294edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 295edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 296edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 297edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public void onBackPressed() { 2982426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann close(true); 299edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 300edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 30181281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan /** Assign this string to the view if it is not empty. */ 30281281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan private void setHeaderNameText(int id, int resId) { 30381281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan setHeaderNameText(id, getText(resId)); 30481281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan } 30581281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan 30681281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan /** Assign this string to the view if it is not empty. */ 30781281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan private void setHeaderNameText(int id, CharSequence value) { 30881281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan final View view = mPhotoContainer.findViewById(id); 30981281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan if (view instanceof TextView) { 31081281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan if (!TextUtils.isEmpty(value)) { 31181281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan ((TextView)view).setText(value); 31281281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan } 31381281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan } 31481281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan } 31581281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan 31681281eefd5aaf339cbfa080ddfa6c6f63caca71aKatherine Kuan /** 317edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * Check if the given MIME-type appears in the list of excluded MIME-types 318edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * that the most-recent caller requested. 319edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann */ 320edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private boolean isMimeExcluded(String mimeType) { 321edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann if (mExcludeMimes == null) return false; 322edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann for (String excludedMime : mExcludeMimes) { 323edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann if (TextUtils.equals(excludedMime, mimeType)) { 324edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann return true; 325edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 326edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 327edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann return false; 328edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 329edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 330edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann /** 331cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann * Handle the result from the ContactLoader 332edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann */ 333851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu private void bindData(Contact data) { 334edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final ResolveCache cache = ResolveCache.getInstance(this); 335edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final Context context = this; 336edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 3379d85a2a39a4b9a0bacee8d25b2830784caf8551cYorke Lee mOpenDetailsImage.setVisibility(isMimeExcluded(Contacts.CONTENT_ITEM_TYPE) ? View.GONE 338edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann : View.VISIBLE); 339edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 340edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mDefaultsMap.clear(); 341edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 342851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu mStopWatch.lap("sph"); // Start photo setting 343dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 344edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final ImageView photoView = (ImageView) mPhotoContainer.findViewById(R.id.photo); 3459758a92fac3e9f64892d893c992f6020d7fe3bfdJosh Gargus mPhotoSetter.setupContactPhoto(data, photoView); 346edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 347dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("ph"); // Photo set 348dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 349851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu for (RawContact rawContact : data.getRawContacts()) { 350851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu for (DataItem dataItem : rawContact.getDataItems()) { 351851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final String mimeType = dataItem.getMimeType(); 35247b6f70eadb118d815b4aaf5426c070bd75a38fbChiao Cheng final AccountType accountType = rawContact.getAccountType(this); 35347b6f70eadb118d815b4aaf5426c070bd75a38fbChiao Cheng final DataKind dataKind = AccountTypeManager.getInstance(this) 35447b6f70eadb118d815b4aaf5426c070bd75a38fbChiao Cheng .getKindOrFallback(accountType, mimeType); 355cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann 356cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann // Skip this data item if MIME-type excluded 357cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann if (isMimeExcluded(mimeType)) continue; 358cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann 359851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final long dataId = dataItem.getId(); 360851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final boolean isPrimary = dataItem.isPrimary(); 361851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final boolean isSuperPrimary = dataItem.isSuperPrimary(); 362cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann 36347b6f70eadb118d815b4aaf5426c070bd75a38fbChiao Cheng if (dataKind != null) { 364cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann // Build an action for this data entry, find a mapping to a UI 365cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann // element, build its summary from the cursor, and collect it 366cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann // along with all others of this MIME-type. 36747b6f70eadb118d815b4aaf5426c070bd75a38fbChiao Cheng final Action action = new DataAction(context, dataItem, dataKind); 3688a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu final boolean wasAdded = considerAdd(action, cache, isSuperPrimary); 369cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann if (wasAdded) { 370cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann // Remember the default 371cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann if (isSuperPrimary || (isPrimary && (mDefaultsMap.get(mimeType) == null))) { 372cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann mDefaultsMap.put(mimeType, action); 373edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 374edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 375edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 376edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 377cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann // Handle Email rows with presence data as Im entry 3789daca14706f3699c9e9d46dfb522132fc566e57eDaniel Lehmann final DataStatus status = data.getStatuses().get(dataId); 379851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu if (status != null && dataItem instanceof EmailDataItem) { 380851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final EmailDataItem email = (EmailDataItem) dataItem; 381851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final ImDataItem im = ImDataItem.createFromEmail(email); 38247b6f70eadb118d815b4aaf5426c070bd75a38fbChiao Cheng if (dataKind != null) { 38347b6f70eadb118d815b4aaf5426c070bd75a38fbChiao Cheng final DataAction action = new DataAction(context, im, dataKind); 3849daca14706f3699c9e9d46dfb522132fc566e57eDaniel Lehmann action.setPresence(status.getPresence()); 3858a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu considerAdd(action, cache, isSuperPrimary); 386cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann } 387edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 388edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 389edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 390edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 391dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("e"); // Entities inflated 392dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 393edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // Collapse Action Lists (remove e.g. duplicate e-mail addresses from different sources) 394edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann for (List<Action> actionChildren : mActions.values()) { 395edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann Collapser.collapseList(actionChildren); 396edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 397edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 398dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("c"); // List collapsed 399dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 400cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann setHeaderNameText(R.id.name, data.getDisplayName()); 401edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 402edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // All the mime-types to add. 403edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final Set<String> containedTypes = new HashSet<String>(mActions.keySet()); 404edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mSortedActionMimeTypes.clear(); 405edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // First, add LEADING_MIMETYPES, which are most common. 406edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann for (String mimeType : LEADING_MIMETYPES) { 407edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann if (containedTypes.contains(mimeType)) { 408edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mSortedActionMimeTypes.add(mimeType); 409edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann containedTypes.remove(mimeType); 410edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 411edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 412edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 413edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // Add all the remaining ones that are not TRAILING 414edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann for (String mimeType : containedTypes.toArray(new String[containedTypes.size()])) { 415edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann if (!TRAILING_MIMETYPES.contains(mimeType)) { 416edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mSortedActionMimeTypes.add(mimeType); 417edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann containedTypes.remove(mimeType); 418edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 419edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 420edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 421edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // Then, add TRAILING_MIMETYPES, which are least common. 422edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann for (String mimeType : TRAILING_MIMETYPES) { 423edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann if (containedTypes.contains(mimeType)) { 424edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann containedTypes.remove(mimeType); 425edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mSortedActionMimeTypes.add(mimeType); 426edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 427edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 428edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 429dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("mt"); // Mime types initialized 430dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 431edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // Add buttons for each mimetype 432cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann mTrack.removeAllViews(); 433edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann for (String mimeType : mSortedActionMimeTypes) { 434edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final View actionView = inflateAction(mimeType, cache, mTrack); 435edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mTrack.addView(actionView); 436edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 437edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 438dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("mt"); // Buttons added 439dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 440edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final boolean hasData = !mSortedActionMimeTypes.isEmpty(); 441edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mTrackScroller.setVisibility(hasData ? View.VISIBLE : View.GONE); 442edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mSelectedTabRectangle.setVisibility(hasData ? View.VISIBLE : View.GONE); 4431792b08c500ed528e7d21401affd936b3a7b3dc6Daniel Lehmann mLineAfterTrack.setVisibility(hasData ? View.VISIBLE : View.GONE); 444edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mListPager.setVisibility(hasData ? View.VISIBLE : View.GONE); 445edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 446edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 447edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann /** 448edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * Consider adding the given {@link Action}, which will only happen if 449edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * {@link PackageManager} finds an application to handle 450edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * {@link Action#getIntent()}. 4518a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu * @param action the action to handle 4528a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu * @param resolveCache cache of applications that can handle actions 4538a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu * @param front indicates whether to add the action to the front of the list 454edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * @return true if action has been added 455edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann */ 4568a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu private boolean considerAdd(Action action, ResolveCache resolveCache, boolean front) { 457edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann if (resolveCache.hasResolve(action)) { 4588a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu mActions.put(action.getMimeType(), action, front); 459edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann return true; 460edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 461edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann return false; 462edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 463edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 464edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann /** 465edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * Inflate the in-track view for the action of the given MIME-type, collapsing duplicate values. 466edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann * Will use the icon provided by the {@link DataKind}. 467edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann */ 468edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private View inflateAction(String mimeType, ResolveCache resolveCache, ViewGroup root) { 469edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final CheckableImageView typeView = (CheckableImageView) getLayoutInflater().inflate( 470edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann R.layout.quickcontact_track_button, root, false); 471edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 472edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann List<Action> children = mActions.get(mimeType); 473edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann typeView.setTag(mimeType); 474edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final Action firstInfo = children.get(0); 475edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 476edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // Set icon and listen for clicks 477edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final CharSequence descrip = resolveCache.getDescription(firstInfo); 478edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final Drawable icon = resolveCache.getIcon(firstInfo); 479edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann typeView.setChecked(false); 480edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann typeView.setContentDescription(descrip); 481edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann typeView.setImageDrawable(icon); 482edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann typeView.setOnClickListener(mTypeViewClickListener); 483edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 484edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann return typeView; 485edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 486edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 487edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private CheckableImageView getActionViewAt(int position) { 488edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann return (CheckableImageView) mTrack.getChildAt(position); 489edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 490edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 491edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 492edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public void onAttachFragment(Fragment fragment) { 493edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final QuickContactListFragment listFragment = (QuickContactListFragment) fragment; 494edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann listFragment.setListener(mListFragmentListener); 495edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 496edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 497851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu private LoaderCallbacks<Contact> mLoaderCallbacks = 498851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu new LoaderCallbacks<Contact>() { 499cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann @Override 500851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public void onLoaderReset(Loader<Contact> loader) { 501cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann } 502cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann 503cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann @Override 504851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public void onLoadFinished(Loader<Contact> loader, Contact data) { 505dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("lf"); // onLoadFinished 506cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann if (isFinishing()) { 5072426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann close(false); 508cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann return; 509cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann } 510cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann if (data.isError()) { 511cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann // This shouldn't ever happen, so throw an exception. The {@link ContactLoader} 512cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann // should log the actual exception. 513cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann throw new IllegalStateException("Failed to load contact", data.getException()); 514cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann } 515cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann if (data.isNotFound()) { 516cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann Log.i(TAG, "No contact found: " + ((ContactLoader)loader).getLookupUri()); 517cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann Toast.makeText(QuickContactActivity.this, R.string.invalidContactMessage, 518cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann Toast.LENGTH_LONG).show(); 5192426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann close(false); 520cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann return; 521cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann } 522cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann 523cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann bindData(data); 524cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann 525dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.lap("bd"); // bindData finished 526dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki 5272426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann if (TRACE_LAUNCH) android.os.Debug.stopMethodTracing(); 528fc0a89fdb1e0bfe5c47e733f867ca520e117316bMakoto Onuki if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) { 529fc0a89fdb1e0bfe5c47e733f867ca520e117316bMakoto Onuki Log.d(Constants.PERFORMANCE_TAG, "QuickContact shown"); 530fc0a89fdb1e0bfe5c47e733f867ca520e117316bMakoto Onuki } 531cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann 532cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann // Data bound and ready, pull curtain to show. Put this on the Handler to ensure 533cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann // that the layout passes are completed 5346f5557e3dc3cd12182026bdfea17b15d4d9b7dfcJosh Gargus SchedulingUtils.doAfterLayout(mFloatingLayout, new Runnable() { 535cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann @Override 536cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann public void run() { 5372426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann mFloatingLayout.showContent(new Runnable() { 538cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann @Override 539cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann public void run() { 5409815d7f98baf80ce51b0cf1f01f48a3dbb9a9db9Daniel Lehmann mContactLoader.upgradeToFullContact(); 541cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann } 542cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann }); 543cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann } 544cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann }); 545dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch.stopAndLog(TAG, 0); 546dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki mStopWatch = StopWatch.getNullStopWatch(); // We're done with it. 547cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann } 548cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann 549cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann @Override 550851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public Loader<Contact> onCreateLoader(int id, Bundle args) { 551cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann if (mLookupUri == null) { 552cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann Log.wtf(TAG, "Lookup uri wasn't initialized. Loader was started too early"); 553cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann } 55445ee872fe7be69c6b3f0c59167eecd11af467812Makoto Onuki return new ContactLoader(getApplicationContext(), mLookupUri, false); 555cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann } 556cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann }; 557cb8d73fc8ea538d0b63dd77210c05c5b8de32f03Daniel Lehmann 558edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann /** A type (e.g. Call/Addresses was clicked) */ 559edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private final OnClickListener mTypeViewClickListener = new OnClickListener() { 560edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 561edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public void onClick(View view) { 562edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final CheckableImageView actionView = (CheckableImageView)view; 563edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final String mimeType = (String) actionView.getTag(); 564edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann int index = mSortedActionMimeTypes.indexOf(mimeType); 565edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mListPager.setCurrentItem(index, true); 566edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 567edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann }; 568edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 569edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private class ViewPagerAdapter extends FragmentPagerAdapter { 570edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public ViewPagerAdapter(FragmentManager fragmentManager) { 571edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann super(fragmentManager); 572edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 573edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 574edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 575edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public Fragment getItem(int position) { 576edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann QuickContactListFragment fragment = new QuickContactListFragment(); 577edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final String mimeType = mSortedActionMimeTypes.get(position); 578edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final List<Action> actions = mActions.get(mimeType); 579edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann fragment.setActions(actions); 580edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann return fragment; 581edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 582edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 583edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 584edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public int getCount() { 585edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann return mSortedActionMimeTypes.size(); 586edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 587edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 588edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 589edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private class PageChangeListener extends SimpleOnPageChangeListener { 590edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 591edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public void onPageSelected(int position) { 592edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final CheckableImageView actionView = getActionViewAt(position); 593edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mTrackScroller.requestChildRectangleOnScreen(actionView, 594edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann new Rect(0, 0, actionView.getWidth(), actionView.getHeight()), false); 5954c2909075a8271b9478506358c15e55fd458e0ccChiao Cheng renderSelectedRectangle(position, 0); 596edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 597edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 598edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 599edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 6004c2909075a8271b9478506358c15e55fd458e0ccChiao Cheng renderSelectedRectangle(position, positionOffset); 6014c2909075a8271b9478506358c15e55fd458e0ccChiao Cheng } 6024c2909075a8271b9478506358c15e55fd458e0ccChiao Cheng 6034c2909075a8271b9478506358c15e55fd458e0ccChiao Cheng private void renderSelectedRectangle(int position, float positionOffset) { 604edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final RelativeLayout.LayoutParams layoutParams = 605edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann (RelativeLayout.LayoutParams) mSelectedTabRectangle.getLayoutParams(); 6064c2909075a8271b9478506358c15e55fd458e0ccChiao Cheng final int width = layoutParams.width; 607edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann layoutParams.leftMargin = (int) ((position + positionOffset) * width); 608edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann mSelectedTabRectangle.setLayoutParams(layoutParams); 609edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 610edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 611edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 612edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann private final QuickContactListFragment.Listener mListFragmentListener = 613edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann new QuickContactListFragment.Listener() { 614edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 615edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public void onOutsideClick() { 616edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // If there is no background, we want to dismiss, because to the user it seems 617edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // like he had touched outside. If the ViewPager is solid however, those taps 618edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // must be ignored 619edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final boolean isTransparent = mListPager.getBackground() == null; 620edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann if (isTransparent) handleOutsideTouch(); 621edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 622edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 623edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 624edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public void onItemClicked(final Action action, final boolean alternate) { 625edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann final Runnable startAppRunnable = new Runnable() { 626edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann @Override 627edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann public void run() { 628edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann try { 629edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann startActivity(alternate ? action.getAlternateIntent() : action.getIntent()); 630edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } catch (ActivityNotFoundException e) { 631edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann Toast.makeText(QuickContactActivity.this, R.string.quickcontact_missing_app, 632edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann Toast.LENGTH_SHORT).show(); 633edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 634edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann 6352426cb015ba4cb679a525bd1ffe223527375468cDaniel Lehmann close(false); 636edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 637edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann }; 638edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann // Defer the action to make the window properly repaint 639edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann new Handler().post(startAppRunnable); 640edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann } 641edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann }; 642edb576aab33efff623691a89ace3c76cb2ff12d1Daniel Lehmann} 643