1ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani/*
2ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * Copyright (C) 2013 The Android Open Source Project
3ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani *
4ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * Licensed under the Apache License, Version 2.0 (the "License");
5ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * you may not use this file except in compliance with the License.
6ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * You may obtain a copy of the License at
7ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani *
8ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani *      http://www.apache.org/licenses/LICENSE-2.0
9ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani *
10ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * Unless required by applicable law or agreed to in writing, software
11ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * distributed under the License is distributed on an "AS IS" BASIS,
12ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * See the License for the specific language governing permissions and
14ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * limitations under the License.
15ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani */
16ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
17ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasanipackage com.android.settings.users;
18ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
19ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.app.Activity;
20ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.app.Fragment;
21ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.content.ClipData;
22ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.content.Context;
23ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.content.Intent;
24ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.content.pm.PackageManager;
25ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.database.Cursor;
26ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.Bitmap;
27ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.BitmapFactory;
28ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.Canvas;
29ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.Paint;
30ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.Rect;
31ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.Bitmap.Config;
32ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.drawable.Drawable;
33ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.net.Uri;
34ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.os.AsyncTask;
35ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.provider.MediaStore;
36ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.provider.ContactsContract.DisplayPhoto;
37ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.support.v4.content.FileProvider;
382a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglioimport android.util.Log;
39ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.view.View;
40ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.view.View.OnClickListener;
41ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.widget.AdapterView;
42ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.widget.ArrayAdapter;
43ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.widget.ImageView;
44ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.widget.ListAdapter;
45ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.widget.ListPopupWindow;
46ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
47ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport com.android.settings.R;
48fe47a8dc89fe0393dae16b1c2152c901feab4dcbAlexandra Gherghinaimport com.android.settings.drawable.CircleFramedDrawable;
49ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
50ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport java.io.File;
51ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport java.io.FileNotFoundException;
522a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglioimport java.io.IOException;
53ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport java.io.InputStream;
54ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport java.util.ArrayList;
55ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport java.util.List;
56ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
57ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasanipublic class EditUserPhotoController {
582a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio    private static final String TAG = "EditUserPhotoController";
592a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio
60ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private static final int POPUP_LIST_ITEM_ID_CHOOSE_PHOTO = 1;
61ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private static final int POPUP_LIST_ITEM_ID_TAKE_PHOTO = 2;
62ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
63ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    // It seems that this class generates custom request codes and they may
64ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    // collide with ours, these values are very unlikely to have a conflict.
65ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private static final int REQUEST_CODE_CHOOSE_PHOTO = 1001;
66ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private static final int REQUEST_CODE_TAKE_PHOTO   = 1002;
67ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private static final int REQUEST_CODE_CROP_PHOTO   = 1003;
68ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
69ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private static final String CROP_PICTURE_FILE_NAME = "CropEditUserPhoto.jpg";
70ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private static final String TAKE_PICTURE_FILE_NAME = "TakeEditUserPhoto2.jpg";
71ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
72ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private final int mPhotoSize;
73ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
74ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private final Context mContext;
75ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private final Fragment mFragment;
76ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private final ImageView mImageView;
77ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
78ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private final Uri mCropPictureUri;
79ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private final Uri mTakePictureUri;
80ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
81ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private Bitmap mNewUserPhotoBitmap;
82ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private Drawable mNewUserPhotoDrawable;
83ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
84ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    public EditUserPhotoController(Fragment fragment, ImageView view,
85ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            Bitmap bitmap, Drawable drawable, boolean waiting) {
86ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        mContext = view.getContext();
87ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        mFragment = fragment;
88ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        mImageView = view;
89ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        mCropPictureUri = createTempImageUri(mContext, CROP_PICTURE_FILE_NAME, !waiting);
90ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        mTakePictureUri = createTempImageUri(mContext, TAKE_PICTURE_FILE_NAME, !waiting);
91ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        mPhotoSize = getPhotoSize(mContext);
92ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        mImageView.setOnClickListener(new OnClickListener() {
93ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            @Override
94ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            public void onClick(View v) {
95ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                showUpdatePhotoPopup();
96ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            }
97ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        });
98ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        mNewUserPhotoBitmap = bitmap;
99ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        mNewUserPhotoDrawable = drawable;
100ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
101ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
102ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
103ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        if (resultCode != Activity.RESULT_OK) {
104ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            return false;
105ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        }
106ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        final Uri pictureUri = data != null && data.getData() != null
107ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                ? data.getData() : mTakePictureUri;
108ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        switch (requestCode) {
109ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            case REQUEST_CODE_CROP_PHOTO:
110ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                onPhotoCropped(pictureUri, true);
111ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                return true;
112ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            case REQUEST_CODE_TAKE_PHOTO:
113ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            case REQUEST_CODE_CHOOSE_PHOTO:
114ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                cropPhoto(pictureUri);
115ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                return true;
116ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        }
117ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        return false;
118ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
119ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
120ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    public Bitmap getNewUserPhotoBitmap() {
121ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        return mNewUserPhotoBitmap;
122ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
123ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
124ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    public Drawable getNewUserPhotoDrawable() {
125ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        return mNewUserPhotoDrawable;
126ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
127ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
128ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private void showUpdatePhotoPopup() {
129ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        final boolean canTakePhoto = canTakePhoto();
130ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        final boolean canChoosePhoto = canChoosePhoto();
131ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
132ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        if (!canTakePhoto && !canChoosePhoto) {
133ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            return;
134ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        }
135ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
136ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        Context context = mImageView.getContext();
137ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        final List<EditUserPhotoController.AdapterItem> items = new ArrayList<EditUserPhotoController.AdapterItem>();
138ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
139ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        if (canTakePhoto()) {
140ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            String title = mImageView.getContext().getString( R.string.user_image_take_photo);
141ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            EditUserPhotoController.AdapterItem item = new AdapterItem(title, POPUP_LIST_ITEM_ID_TAKE_PHOTO);
142ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            items.add(item);
143ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        }
144ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
145ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        if (canChoosePhoto) {
146ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            String title = context.getString(R.string.user_image_choose_photo);
147ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            EditUserPhotoController.AdapterItem item = new AdapterItem(title, POPUP_LIST_ITEM_ID_CHOOSE_PHOTO);
148ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            items.add(item);
149ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        }
150ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
151ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        final ListPopupWindow listPopupWindow = new ListPopupWindow(context);
152ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
153ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        listPopupWindow.setAnchorView(mImageView);
154ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        listPopupWindow.setModal(true);
155ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        listPopupWindow.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
156ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
157ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        ListAdapter adapter = new ArrayAdapter<EditUserPhotoController.AdapterItem>(context,
158ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                R.layout.edit_user_photo_popup_item, items);
159ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        listPopupWindow.setAdapter(adapter);
160ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
161ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        final int width = Math.max(mImageView.getWidth(), context.getResources()
162ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                .getDimensionPixelSize(R.dimen.update_user_photo_popup_min_width));
163ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        listPopupWindow.setWidth(width);
164ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
165ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        listPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
166ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            @Override
167ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
168ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                EditUserPhotoController.AdapterItem item = items.get(position);
169ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                switch (item.id) {
170ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    case POPUP_LIST_ITEM_ID_CHOOSE_PHOTO: {
171ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        choosePhoto();
172ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        listPopupWindow.dismiss();
173ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    } break;
174ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    case POPUP_LIST_ITEM_ID_TAKE_PHOTO: {
175ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        takePhoto();
176ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        listPopupWindow.dismiss();
177ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    } break;
178ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                }
179ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            }
180ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        });
181ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
182ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        listPopupWindow.show();
183ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
184ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
185ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private boolean canTakePhoto() {
186ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        return mImageView.getContext().getPackageManager().queryIntentActivities(
187ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
188ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
189ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
190ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
191ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private boolean canChoosePhoto() {
192ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
193ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.setType("image/*");
194ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        return mImageView.getContext().getPackageManager().queryIntentActivities(
195ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                intent, 0).size() > 0;
196ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
197ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
198ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private void takePhoto() {
199ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
200ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        appendOutputExtra(intent, mTakePictureUri);
201ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        mFragment.startActivityForResult(intent, REQUEST_CODE_TAKE_PHOTO);
202ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
203ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
204ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private void choosePhoto() {
205ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
206ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.setType("image/*");
207ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        appendOutputExtra(intent, mTakePictureUri);
208ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        mFragment.startActivityForResult(intent, REQUEST_CODE_CHOOSE_PHOTO);
209ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
210ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
211ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private void cropPhoto(Uri pictureUri) {
212ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        // TODO: Use a public intent, when there is one.
213ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        Intent intent = new Intent("com.android.camera.action.CROP");
214ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.setDataAndType(pictureUri, "image/*");
215ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        appendOutputExtra(intent, mCropPictureUri);
216ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        appendCropExtras(intent);
217ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        if (intent.resolveActivity(mContext.getPackageManager()) != null) {
218ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            mFragment.startActivityForResult(intent, REQUEST_CODE_CROP_PHOTO);
219ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        } else {
220ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            onPhotoCropped(pictureUri, false);
221ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        }
222ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
223ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
224ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private void appendOutputExtra(Intent intent, Uri pictureUri) {
225ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.putExtra(MediaStore.EXTRA_OUTPUT, pictureUri);
226ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
227ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                | Intent.FLAG_GRANT_READ_URI_PERMISSION);
228ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.setClipData(ClipData.newRawUri(MediaStore.EXTRA_OUTPUT, pictureUri));
229ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
230ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
231ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private void appendCropExtras(Intent intent) {
232ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.putExtra("crop", "true");
233ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.putExtra("scale", true);
234ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.putExtra("scaleUpIfNeeded", true);
235ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.putExtra("aspectX", 1);
236ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.putExtra("aspectY", 1);
237ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.putExtra("outputX", mPhotoSize);
238ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        intent.putExtra("outputY", mPhotoSize);
239ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
240ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
241ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private void onPhotoCropped(final Uri data, final boolean cropped) {
242ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        new AsyncTask<Void, Void, Bitmap>() {
243ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            @Override
244ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            protected Bitmap doInBackground(Void... params) {
245ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                if (cropped) {
2462a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio                    InputStream imageStream = null;
247ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    try {
2482a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio                        imageStream = mContext.getContentResolver()
249ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                                .openInputStream(data);
250ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        return BitmapFactory.decodeStream(imageStream);
251ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    } catch (FileNotFoundException fe) {
2522a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio                        Log.w(TAG, "Cannot find image file", fe);
253ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        return null;
2542a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio                    } finally {
2552a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio                        if (imageStream != null) {
2562a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio                            try {
2572a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio                                imageStream.close();
2582a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio                            } catch (IOException ioe) {
2592a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio                                Log.w(TAG, "Cannot close image stream", ioe);
2602a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio                            }
2612a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio                        }
262ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    }
263ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                } else {
264ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    // Scale and crop to a square aspect ratio
265ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    Bitmap croppedImage = Bitmap.createBitmap(mPhotoSize, mPhotoSize,
266ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                            Config.ARGB_8888);
267ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    Canvas canvas = new Canvas(croppedImage);
268ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    Bitmap fullImage = null;
269ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    try {
270ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        InputStream imageStream = mContext.getContentResolver()
271ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                                .openInputStream(data);
272ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        fullImage = BitmapFactory.decodeStream(imageStream);
273ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    } catch (FileNotFoundException fe) {
274ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        return null;
275ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    }
276ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    if (fullImage != null) {
277ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        final int squareSize = Math.min(fullImage.getWidth(),
278ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                                fullImage.getHeight());
279ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        final int left = (fullImage.getWidth() - squareSize) / 2;
280ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        final int top = (fullImage.getHeight() - squareSize) / 2;
281ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        Rect rectSource = new Rect(left, top,
282ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                                left + squareSize, top + squareSize);
283ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        Rect rectDest = new Rect(0, 0, mPhotoSize, mPhotoSize);
284ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        Paint paint = new Paint();
285ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        canvas.drawBitmap(fullImage, rectSource, rectDest, paint);
286ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        return croppedImage;
287ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    } else {
288ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        // Bah! Got nothin.
289ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                        return null;
290ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    }
291ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                }
292ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            }
293ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
294ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            @Override
295ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            protected void onPostExecute(Bitmap bitmap) {
296ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                if (bitmap != null) {
297ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    mNewUserPhotoBitmap = bitmap;
298ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    mNewUserPhotoDrawable = CircleFramedDrawable
299ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                            .getInstance(mImageView.getContext(), mNewUserPhotoBitmap);
300ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                    mImageView.setImageDrawable(mNewUserPhotoDrawable);
301ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                }
302ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                new File(mContext.getCacheDir(), TAKE_PICTURE_FILE_NAME).delete();
303ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                new File(mContext.getCacheDir(), CROP_PICTURE_FILE_NAME).delete();
304ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            }
305ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
306ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
307ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
308ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private static int getPhotoSize(Context context) {
309ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        Cursor cursor = context.getContentResolver().query(
310ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI,
311ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                new String[]{DisplayPhoto.DISPLAY_MAX_DIM}, null, null, null);
312ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        try {
313ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            cursor.moveToFirst();
314ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            return cursor.getInt(0);
315ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        } finally {
316ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            cursor.close();
317ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        }
318ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
319ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
320ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private Uri createTempImageUri(Context context, String fileName, boolean purge) {
321ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        final File folder = context.getCacheDir();
322ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        folder.mkdirs();
323ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        final File fullPath = new File(folder, fileName);
324ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        if (purge) {
325ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            fullPath.delete();
326ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        }
327ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        final Uri fileUri =
328ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani                FileProvider.getUriForFile(context, RestrictedProfileSettings.FILE_PROVIDER_AUTHORITY, fullPath);
329ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        return fileUri;
330ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
331ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
332ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    private static final class AdapterItem {
333ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        final String title;
334ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        final int id;
335ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
336ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        public AdapterItem(String title, int id) {
337ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            this.title = title;
338ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            this.id = id;
339ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        }
340ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani
341ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        @Override
342ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        public String toString() {
343ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani            return title;
344ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani        }
345ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani    }
346ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani}