PhotoSelectionActivity.java revision 51f9c0f2f2923d14cced5096b40f017dd87b68d3
16fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro/* 26fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * Copyright (C) 2011 The Android Open Source Project 36fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * 46fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * Licensed under the Apache License, Version 2.0 (the "License"); 56fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * you may not use this file except in compliance with the License. 66fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * You may obtain a copy of the License at 76fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * 86fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * http://www.apache.org/licenses/LICENSE-2.0 96fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * 106fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * Unless required by applicable law or agreed to in writing, software 116fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * distributed under the License is distributed on an "AS IS" BASIS, 126fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * See the License for the specific language governing permissions and 146fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * limitations under the License. 156fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro */ 166fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoropackage com.android.contacts.activities; 176fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1814d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoroimport com.android.contacts.ContactPhotoManager; 196fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport com.android.contacts.ContactSaveService; 206fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport com.android.contacts.R; 216fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport com.android.contacts.detail.PhotoSelectionHandler; 226fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport com.android.contacts.editor.PhotoActionPopup; 236fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport com.android.contacts.model.EntityDeltaList; 2451f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargusimport com.android.contacts.util.AnimationUtils; 256fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 266fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.animation.Animator; 276fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.animation.AnimatorListenerAdapter; 286fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.animation.ObjectAnimator; 296fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.animation.PropertyValuesHolder; 306fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.app.Activity; 316fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.content.Context; 326fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.content.Intent; 336fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.graphics.Bitmap; 346fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.graphics.Rect; 3514d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoroimport android.net.Uri; 366fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.os.Bundle; 376fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.os.Parcelable; 386fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.view.View; 396fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.view.ViewGroup.MarginLayoutParams; 406fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.view.ViewTreeObserver.OnGlobalLayoutListener; 416fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.widget.FrameLayout.LayoutParams; 426fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport android.widget.ImageView; 436fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 446fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoroimport java.io.File; 456fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 466fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro/** 476fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * Popup activity for choosing a contact photo within the Contacts app. 486fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro */ 496fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoropublic class PhotoSelectionActivity extends Activity { 506fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 516fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Number of ms for the animation to expand the photo. */ 526fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private static final int PHOTO_EXPAND_DURATION = 100; 536fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 546fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Number of ms for the animation to contract the photo on activity exit. */ 556fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private static final int PHOTO_CONTRACT_DURATION = 50; 566fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 576fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Number of ms for the animation to hide the backdrop on finish. */ 586fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private static final int BACKDROP_FADEOUT_DURATION = 100; 596fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 606fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private static final String KEY_CURRENT_PHOTO_FILE = "currentphotofile"; 616fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 626fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private static final String KEY_SUB_ACTIVITY_IN_PROGRESS = "subinprogress"; 636fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 6414d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro /** Intent extra to get the photo URI. */ 6514d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro public static final String PHOTO_URI = "photo_uri"; 666fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 676fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Intent extra to get the entity delta list. */ 686fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public static final String ENTITY_DELTA_LIST = "entity_delta_list"; 696fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 706fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Intent extra to indicate whether the contact is the user's profile. */ 716fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public static final String IS_PROFILE = "is_profile"; 726fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 736fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Intent extra to indicate whether the contact is from a directory (non-editable). */ 746fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public static final String IS_DIRECTORY_CONTACT = "is_directory_contact"; 756fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 766fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** 776fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * Intent extra to indicate whether the photo should be animated to show the full contents of 786fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * the photo (on a larger portion of the screen) when clicked. If unspecified or false, the 796fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * photo will not move from its original location. 806fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro */ 816fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public static final String EXPAND_PHOTO = "expand_photo"; 826fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 836fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Source bounds of the image that was clicked on. */ 846fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private Rect mSourceBounds; 856fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 8614d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro /** 8714d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro * The photo URI. May be null, in which case the default avatar will be used. 8814d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro */ 8914d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro private Uri mPhotoUri; 906fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 916fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Entity delta list of the contact. */ 926fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private EntityDeltaList mState; 936fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 946fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Whether the contact is the user's profile. */ 956fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private boolean mIsProfile; 966fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 976fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Whether the contact is from a directory. */ 986fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private boolean mIsDirectoryContact; 996fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1006fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Whether to animate the photo to an expanded view covering more of the screen. */ 1016fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private boolean mExpandPhoto; 1026fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1036fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** The semi-transparent backdrop. */ 1046fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private View mBackdrop; 1056fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1066fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** The photo view. */ 1076fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private ImageView mPhotoView; 1086fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1096fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** The photo handler attached to this activity, if any. */ 1106fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private PhotoHandler mPhotoHandler; 1116fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1126fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Animator to expand the photo out to full size. */ 1136fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private ObjectAnimator mPhotoAnimator; 1146fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1156fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Listener for the animation. */ 1166fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private AnimatorListenerAdapter mAnimationListener; 1176fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1186fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Whether a change in layout of the photo has occurred that has no animation yet. */ 1196fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private boolean mAnimationPending; 1206fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1216fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Prior position of the image (for animating). */ 1226fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro Rect mOriginalPos = new Rect(); 1236fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1246fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Layout params for the photo view before we started animating. */ 1256fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private LayoutParams mPhotoStartParams; 1266fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1276fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Layout params for the photo view after we finished animating. */ 1286fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private LayoutParams mPhotoEndParams; 1296fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1306fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** Whether a sub-activity is currently in progress. */ 1316fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private boolean mSubActivityInProgress; 1326fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1336fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** 1346fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * A photo result received by the activity, persisted across activity lifecycle. 1356fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro */ 1366fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private PendingPhotoResult mPendingPhotoResult; 1376fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1386fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** 1396fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * The photo file being interacted with, if any. Saved/restored between activity instances. 1406fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro */ 1416fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private File mCurrentPhotoFile; 1426fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1436fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 1446fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro protected void onCreate(Bundle savedInstanceState) { 1456fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro super.onCreate(savedInstanceState); 1466fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro setContentView(R.layout.photoselection_activity); 1476fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (savedInstanceState != null) { 1486fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro String fileName = savedInstanceState.getString(KEY_CURRENT_PHOTO_FILE); 1496fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (fileName != null) { 1506fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mCurrentPhotoFile = new File(fileName); 1516fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 1526fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mSubActivityInProgress = savedInstanceState.getBoolean(KEY_SUB_ACTIVITY_IN_PROGRESS); 1536fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 1546fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1556fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Pull data out of the intent. 1566fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro final Intent intent = getIntent(); 15714d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mPhotoUri = intent.getParcelableExtra(PHOTO_URI); 1586fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mState = (EntityDeltaList) intent.getParcelableExtra(ENTITY_DELTA_LIST); 1596fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mIsProfile = intent.getBooleanExtra(IS_PROFILE, false); 1606fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mIsDirectoryContact = intent.getBooleanExtra(IS_DIRECTORY_CONTACT, false); 1616fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mExpandPhoto = intent.getBooleanExtra(EXPAND_PHOTO, false); 1626fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1636fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mBackdrop = findViewById(R.id.backdrop); 1646fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoView = (ImageView) findViewById(R.id.photo); 1656fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mSourceBounds = intent.getSourceBounds(); 1666fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1676fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Fade in the background. 1686fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro animateInBackground(); 1696fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1706fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Dismiss the dialog on clicking the backdrop. 1716fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mBackdrop.setOnClickListener(new View.OnClickListener() { 1726fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 1736fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onClick(View v) { 1746fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro finish(); 1756fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 1766fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro }); 1776fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1786fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Wait until the layout pass to show the photo, so that the source bounds will match up. 17951f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargus AnimationUtils.doAfterLayout(mBackdrop, new Runnable() { 1806fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 18151f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargus public void run() { 1826fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro displayPhoto(); 1836fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 18451f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargus }); 1856fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 1866fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1876fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 1886fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void finish() { 1896fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (!mSubActivityInProgress) { 1906fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro closePhotoAndFinish(); 1916fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } else { 1926fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro activityFinish(); 1936fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 1946fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 1956fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 1966fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** 1976fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * Builds a well-formed intent for invoking this activity. 1986fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * @param context The context. 19914d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro * @param photoUri The URI of the current photo (may be null, in which case the default 20014d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro * avatar image will be displayed). 20114d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro * @param photoBitmap The bitmap of the current photo (may be null, in which case the default 20214d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro * avatar image will be displayed). 20314d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro * @param photoBytes The bytes for the current photo (may be null, in which case the default 20414d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro * avatar image will be displayed). 2056fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * @param photoBounds The pixel bounds of the current photo. 2066fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * @param delta The entity delta list for the contact. 2076fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * @param isProfile Whether the contact is the user's profile. 2086fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * @param isDirectoryContact Whether the contact comes from a directory (non-editable). 2096fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * @param expandPhotoOnClick Whether the photo should be expanded on click or not (generally, 2106fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * this should be true for phones, and false for tablets). 2116fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * @return An intent that can be used to invoke the photo selection activity. 2126fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro */ 21314d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro public static Intent buildIntent(Context context, Uri photoUri, Bitmap photoBitmap, 21414d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro byte[] photoBytes, Rect photoBounds, EntityDeltaList delta, boolean isProfile, 21514d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro boolean isDirectoryContact, boolean expandPhotoOnClick) { 2166fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro Intent intent = new Intent(context, PhotoSelectionActivity.class); 21714d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro if (photoUri != null && photoBitmap != null && photoBytes != null) { 21814d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro intent.putExtra(PHOTO_URI, photoUri); 21914d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro } 2206fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro intent.setSourceBounds(photoBounds); 2216fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro intent.putExtra(ENTITY_DELTA_LIST, (Parcelable) delta); 2226fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro intent.putExtra(IS_PROFILE, isProfile); 2236fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro intent.putExtra(IS_DIRECTORY_CONTACT, isDirectoryContact); 2246fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro intent.putExtra(EXPAND_PHOTO, expandPhotoOnClick); 2256fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro return intent; 2266fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 2276fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 2286fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private void activityFinish() { 2296fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro super.finish(); 2306fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 2316fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 2326fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 2336fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro protected void onDestroy() { 2346fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro super.onDestroy(); 2356fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (mPhotoAnimator != null) { 2366fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoAnimator.cancel(); 2376fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoAnimator = null; 2386fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 2396fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (mPhotoHandler != null) { 2406fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoHandler.destroy(); 2416fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoHandler = null; 2426fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 2436fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 2446fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 2456fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private void displayPhoto() { 24614d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro // Load the photo. 24714d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro if (mPhotoUri != null) { 24814d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro // If we have a URI, the bitmap should be cached directly. 24914d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro ContactPhotoManager.getInstance(this).loadPhoto(mPhotoView, mPhotoUri, true, false); 25014d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro } else { 25114d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro // Fall back to avatar image. 25214d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mPhotoView.setImageResource(ContactPhotoManager.getDefaultAvatarResId(true, false)); 25314d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro } 25414d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro 25514d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro // Animate the photo view into its end location. 25614d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro final int[] pos = new int[2]; 25714d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mBackdrop.getLocationOnScreen(pos); 25814d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro LayoutParams layoutParams = new LayoutParams(mSourceBounds.width(), 25914d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mSourceBounds.height()); 26014d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mOriginalPos.left = mSourceBounds.left - pos[0]; 26114d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mOriginalPos.top = mSourceBounds.top - pos[1]; 26214d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mOriginalPos.right = mOriginalPos.left + mSourceBounds.width(); 26314d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mOriginalPos.bottom = mOriginalPos.top + mSourceBounds.height(); 26414d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro layoutParams.setMargins(mOriginalPos.left, mOriginalPos.top, mOriginalPos.right, 26514d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mOriginalPos.bottom); 26614d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mPhotoStartParams = layoutParams; 26714d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mPhotoView.setLayoutParams(layoutParams); 26814d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mPhotoView.requestLayout(); 26914d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro 27014d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mPhotoView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 27114d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro @Override 27214d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro public void onLayoutChange(View v, int left, int top, int right, int bottom, 27314d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro int oldLeft, int oldTop, int oldRight, int oldBottom) { 27414d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro if (mAnimationPending) { 27514d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro mAnimationPending = false; 27614d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro PropertyValuesHolder pvhLeft = 27714d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro PropertyValuesHolder.ofInt("left", mOriginalPos.left, left); 27814d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro PropertyValuesHolder pvhTop = 27914d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro PropertyValuesHolder.ofInt("top", mOriginalPos.top, top); 28014d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro PropertyValuesHolder pvhRight = 28114d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro PropertyValuesHolder.ofInt("right", mOriginalPos.right, right); 28214d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro PropertyValuesHolder pvhBottom = 28314d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro PropertyValuesHolder.ofInt("bottom", mOriginalPos.bottom, bottom); 28414d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(mPhotoView, 28514d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro pvhLeft, pvhTop, pvhRight, pvhBottom).setDuration( 28614d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro PHOTO_EXPAND_DURATION); 28714d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro if (mAnimationListener != null) { 28814d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro anim.addListener(mAnimationListener); 2896fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 29014d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro anim.start(); 2916fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 29214d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro } 29314d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro }); 29414d2083c4c4c52b0d8b600a93c294af32cd6a826Dave Santoro attachPhotoHandler(); 2956fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 2966fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 2976fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private LayoutParams getPhotoEndParams() { 2986fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (mPhotoEndParams == null) { 2996fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoEndParams = new LayoutParams(mPhotoStartParams); 3006fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (mExpandPhoto) { 3016fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro Rect bounds = new Rect(); 3026fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mBackdrop.getDrawingRect(bounds); 3036fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (bounds.height() > bounds.width()) { 3046fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro //Take up full width. 3056fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoEndParams.width = bounds.width(); 3066fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoEndParams.height = bounds.width(); 3076fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } else { 3086fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Take up full height, leaving space for the popup. 3096fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoEndParams.height = bounds.height() - 150; 3106fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoEndParams.width = bounds.height() - 150; 3116fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3126fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoEndParams.topMargin = 0; 3136fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoEndParams.leftMargin = 0; 3146fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoEndParams.bottomMargin = mPhotoEndParams.height; 3156fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoEndParams.rightMargin = mPhotoEndParams.width; 3166fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3176fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3186fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro return mPhotoEndParams; 3196fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3206fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 3216fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private void animatePhotoOpen() { 3226fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mAnimationListener = new AnimatorListenerAdapter() { 3236fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private void capturePhotoPos() { 3246fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoView.requestLayout(); 3256fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mOriginalPos.left = mPhotoView.getLeft(); 3266fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mOriginalPos.top = mPhotoView.getTop(); 3276fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mOriginalPos.right = mPhotoView.getRight(); 3286fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mOriginalPos.bottom = mPhotoView.getBottom(); 3296fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3306fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 3316fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 3326fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onAnimationEnd(Animator animation) { 3336fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro capturePhotoPos(); 3346fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (mPhotoHandler != null) { 3356fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoHandler.onClick(mPhotoView); 3366fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3376fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3386fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 3396fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 3406fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onAnimationCancel(Animator animation) { 3416fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro capturePhotoPos(); 3426fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3436fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro }; 3446fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro animatePhoto(getPhotoEndParams()); 3456fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3466fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 3476fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private void closePhotoAndFinish() { 3486fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mAnimationListener = new AnimatorListenerAdapter() { 3496fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 3506fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onAnimationEnd(Animator animation) { 3516fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // After the photo animates down, fade it away and finish. 3526fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro ObjectAnimator anim = ObjectAnimator.ofFloat( 3536fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoView, "alpha", 0f).setDuration(PHOTO_CONTRACT_DURATION); 3546fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro anim.addListener(new AnimatorListenerAdapter() { 3556fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 3566fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onAnimationEnd(Animator animation) { 3576fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro activityFinish(); 3586fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3596fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro }); 3606fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro anim.start(); 3616fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3626fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro }; 3636fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 3646fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // TODO: This won't animate in the right way if the rotation has changed since the activity 3656fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // was first started. 3666fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro animatePhoto(mPhotoStartParams); 3676fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro animateAwayBackground(); 3686fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3696fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 3706fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private void animatePhoto(MarginLayoutParams to) { 3716fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Cancel any existing animation. 3726fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (mPhotoAnimator != null) { 3736fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoAnimator.cancel(); 3746fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3756fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 3766fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoView.setLayoutParams(to); 3776fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mAnimationPending = true; 3786fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoView.requestLayout(); 3796fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3806fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 3816fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private void animateInBackground() { 3826fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro ObjectAnimator.ofFloat(mBackdrop, "alpha", 0, 0.5f).setDuration( 3836fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro PHOTO_EXPAND_DURATION).start(); 3846fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3856fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 3866fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private void animateAwayBackground() { 3876fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro ObjectAnimator.ofFloat(mBackdrop, "alpha", 0f).setDuration( 3886fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro BACKDROP_FADEOUT_DURATION).start(); 3896fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3906fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 3916fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 3926fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro protected void onSaveInstanceState(Bundle outState) { 3936fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro super.onSaveInstanceState(outState); 3946fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (mCurrentPhotoFile != null) { 3956fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro outState.putString(KEY_CURRENT_PHOTO_FILE, mCurrentPhotoFile.toString()); 3966fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3976fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro outState.putBoolean(KEY_SUB_ACTIVITY_IN_PROGRESS, mSubActivityInProgress); 3986fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 3996fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 4006fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 4016fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro protected void onActivityResult(int requestCode, int resultCode, Intent data) { 4026fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (mPhotoHandler != null) { 4036fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mSubActivityInProgress = false; 4046fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (mPhotoHandler.handlePhotoActivityResult(requestCode, resultCode, data)) { 4056fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Clear out any pending photo result. 4066fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPendingPhotoResult = null; 4076fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } else { 4086fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // User returning to the photo selection activity. Re-display options. 4096fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoHandler.onClick(mPhotoView); 4106fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4116fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } else { 4126fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Create a pending photo result to be handled when the photo handler is created. 4136fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPendingPhotoResult = new PendingPhotoResult(requestCode, resultCode, data); 4146fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4156fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4166fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 4176fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private void attachPhotoHandler() { 418ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus // Always provide the same two choices (take a photo with the camera, select a photo 419ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus // from the gallery), but with slightly different wording. 420ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus // Note: don't worry about this being a read-only contact; this code will not be invoked. 421ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus int mode = (mPhotoUri == null) ? PhotoActionPopup.Modes.NO_PHOTO 422ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus : PhotoActionPopup.Modes.PHOTO_DISALLOW_PRIMARY; 423ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus // We don't want to provide a choice to remove the photo for two reasons: 424ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus // 1) the UX designs don't call for it 425ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus // 2) even if we wanted to, the implementation would be moderately hairy 426ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus mode &= ~PhotoActionPopup.Flags.REMOVE_PHOTO; 427ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus 428ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus mPhotoHandler = new PhotoHandler(this, mPhotoView, mode, mState); 4296fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (mPendingPhotoResult != null) { 4306fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPhotoHandler.handlePhotoActivityResult(mPendingPhotoResult.mRequestCode, 4316fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPendingPhotoResult.mResultCode, mPendingPhotoResult.mData); 4326fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mPendingPhotoResult = null; 4336fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } else { 43451f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargus // Setting the photo in displayPhoto() resulted in a relayout 43551f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargus // request... to avoid jank, wait until this layout has happened. 43651f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargus AnimationUtils.doAfterLayout(mBackdrop, new Runnable() { 43751f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargus @Override 43851f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargus public void run() { 43951f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargus animatePhotoOpen(); 44051f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargus } 44151f9c0f2f2923d14cced5096b40f017dd87b68d3Josh Gargus }); 4426fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4436fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4446fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 4456fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private final class PhotoHandler extends PhotoSelectionHandler { 4466fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private PhotoHandler(Context context, View photoView, int photoMode, 4476fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro EntityDeltaList state) { 4486fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro super(context, photoView, photoMode, mIsDirectoryContact, state); 4496fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro setListener(new PhotoListener(context, mIsProfile)); 4506fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4516fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 4526fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private final class PhotoListener extends PhotoActionListener { 4536fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private final Context mContext; 4546fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private final boolean mIsProfile; 4556fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private PhotoListener(Context context, boolean isProfile) { 4566fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mContext = context; 4576fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mIsProfile = isProfile; 4586fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4596fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 4606fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 4616fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void startTakePhotoActivity(Intent intent, int requestCode, File photoFile) { 4626fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mSubActivityInProgress = true; 4636fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mCurrentPhotoFile = photoFile; 4646fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro startActivityForResult(intent, requestCode); 4656fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4666fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 4676fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 468e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus public void startPickFromGalleryActivity(Intent intent, int requestCode, 469e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus File photoFile) { 4706fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mSubActivityInProgress = true; 471e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus mCurrentPhotoFile = photoFile; 4726fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro startActivityForResult(intent, requestCode); 4736fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4746fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 4756fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 4766fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onPhotoSelected(Bitmap bitmap) { 477e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus EntityDeltaList delta = getDeltaForAttachingPhotoToContact(); 478e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus long rawContactId = getWritableEntityId(); 479e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus String filePath = mCurrentPhotoFile.getAbsolutePath(); 4806fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro Intent intent = ContactSaveService.createSaveContactIntent(mContext, delta, 4816fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro "", 0, mIsProfile, PhotoSelectionActivity.class, 482e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus ContactEditorActivity.ACTION_SAVE_COMPLETED, rawContactId, filePath); 4836fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro startService(intent); 4846fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro finish(); 4856fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4866fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 4876fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 4886fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public File getCurrentPhotoFile() { 4896fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro return mCurrentPhotoFile; 4906fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4916fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 4926fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 4936fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onPhotoSelectionDismissed() { 4946fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (!mSubActivityInProgress) { 4956fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro finish(); 4966fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4976fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4986fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4996fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 5006fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 5016fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private static class PendingPhotoResult { 5026fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private int mRequestCode; 5036fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private int mResultCode; 5046fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private Intent mData; 5056fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private PendingPhotoResult(int requestCode, int resultCode, Intent data) { 5066fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mRequestCode = requestCode; 5076fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mResultCode = resultCode; 5086fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mData = data; 5096fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 5106fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 5116fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro} 512