1666ea1b28a76aeba74744148b15099254d918671Owen Lin/*
2666ea1b28a76aeba74744148b15099254d918671Owen Lin * Copyright (C) 2008 The Android Open Source Project
3666ea1b28a76aeba74744148b15099254d918671Owen Lin *
4666ea1b28a76aeba74744148b15099254d918671Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
5666ea1b28a76aeba74744148b15099254d918671Owen Lin * you may not use this file except in compliance with the License.
6666ea1b28a76aeba74744148b15099254d918671Owen Lin * You may obtain a copy of the License at
7666ea1b28a76aeba74744148b15099254d918671Owen Lin *
8666ea1b28a76aeba74744148b15099254d918671Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
9666ea1b28a76aeba74744148b15099254d918671Owen Lin *
10666ea1b28a76aeba74744148b15099254d918671Owen Lin * Unless required by applicable law or agreed to in writing, software
11666ea1b28a76aeba74744148b15099254d918671Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
12666ea1b28a76aeba74744148b15099254d918671Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13666ea1b28a76aeba74744148b15099254d918671Owen Lin * See the License for the specific language governing permissions and
14666ea1b28a76aeba74744148b15099254d918671Owen Lin * limitations under the License.
15666ea1b28a76aeba74744148b15099254d918671Owen Lin */
16666ea1b28a76aeba74744148b15099254d918671Owen Lin
17666ea1b28a76aeba74744148b15099254d918671Owen Linpackage com.android.camera;
18666ea1b28a76aeba74744148b15099254d918671Owen Lin
19d6c2fb7a38fcdb58742fcfffd67a4594487ec71cOwen Linimport com.android.gallery.R;
20d6c2fb7a38fcdb58742fcfffd67a4594487ec71cOwen Lin
21666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.app.Activity;
22666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.app.AlertDialog;
23666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.content.ActivityNotFoundException;
24666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.content.Context;
25666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.content.DialogInterface;
26666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.content.Intent;
27666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.content.DialogInterface.OnClickListener;
28666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.location.Geocoder;
29666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.media.ExifInterface;
30666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.media.MediaMetadataRetriever;
31666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.net.Uri;
32666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.os.Environment;
33666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.os.Handler;
34666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.os.StatFs;
35666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.preference.PreferenceManager;
36666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.provider.MediaStore;
37666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.provider.MediaStore.Images;
38666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.text.format.Formatter;
39666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.util.Log;
40666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.view.Menu;
41666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.view.MenuItem;
42666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.view.SubMenu;
43666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.view.View;
44666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.widget.ImageView;
45666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.widget.TextView;
46666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.widget.Toast;
47666ea1b28a76aeba74744148b15099254d918671Owen Lin
48666ea1b28a76aeba74744148b15099254d918671Owen Linimport com.android.camera.gallery.IImage;
49666ea1b28a76aeba74744148b15099254d918671Owen Lin
50666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.io.Closeable;
51666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.io.IOException;
52666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.lang.ref.WeakReference;
53666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.text.SimpleDateFormat;
54666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.util.ArrayList;
55666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.util.Date;
56666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.util.List;
57666ea1b28a76aeba74744148b15099254d918671Owen Lin
58666ea1b28a76aeba74744148b15099254d918671Owen Lin/**
59666ea1b28a76aeba74744148b15099254d918671Owen Lin * A utility class to handle various kinds of menu operations.
60666ea1b28a76aeba74744148b15099254d918671Owen Lin */
61666ea1b28a76aeba74744148b15099254d918671Owen Linpublic class MenuHelper {
62666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static final String TAG = "MenuHelper";
63666ea1b28a76aeba74744148b15099254d918671Owen Lin
64666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int INCLUDE_ALL           = 0xFFFFFFFF;
65666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int INCLUDE_VIEWPLAY_MENU = (1 << 0);
66666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int INCLUDE_SHARE_MENU    = (1 << 1);
67666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int INCLUDE_SET_MENU      = (1 << 2);
68666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int INCLUDE_CROP_MENU     = (1 << 3);
69666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int INCLUDE_DELETE_MENU   = (1 << 4);
70666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int INCLUDE_ROTATE_MENU   = (1 << 5);
71666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int INCLUDE_DETAILS_MENU  = (1 << 6);
72666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int INCLUDE_SHOWMAP_MENU  = (1 << 7);
73666ea1b28a76aeba74744148b15099254d918671Owen Lin
74666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int MENU_IMAGE_SHARE = 1;
75666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int MENU_IMAGE_SHOWMAP = 2;
76666ea1b28a76aeba74744148b15099254d918671Owen Lin
77666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_SWITCH_CAMERA_MODE = 1;
78666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_GOTO_GALLERY = 2;
79666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_VIEWPLAY = 3;
80666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_CAPTURE_PICTURE = 4;
81666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_CAPTURE_VIDEO = 5;
82666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_IMAGE_SHARE = 6;
83666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_IMAGE_ROTATE = 7;
84666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_IMAGE_TOSS = 8;
85666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_IMAGE_CROP = 9;
86666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_IMAGE_SET = 10;
87666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_DETAILS = 11;
88666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_SHOWMAP = 12;
89666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_SLIDESHOW = 13;
90666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_MULTISELECT = 14;
91666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_CAMERA_SETTING = 15;
92666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int POSITION_GALLERY_SETTING = 16;
93666ea1b28a76aeba74744148b15099254d918671Owen Lin
94666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int NO_STORAGE_ERROR = -1;
95666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int CANNOT_STAT_ERROR = -2;
96666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final String EMPTY_STRING = "";
97666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final String JPEG_MIME_TYPE = "image/jpeg";
98666ea1b28a76aeba74744148b15099254d918671Owen Lin    // valid range is -180f to +180f
99666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final float INVALID_LATLNG = 255f;
100666ea1b28a76aeba74744148b15099254d918671Owen Lin
101666ea1b28a76aeba74744148b15099254d918671Owen Lin    /** Activity result code used to report crop results.
102666ea1b28a76aeba74744148b15099254d918671Owen Lin     */
103666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static final int RESULT_COMMON_MENU_CROP = 490;
104666ea1b28a76aeba74744148b15099254d918671Owen Lin
105666ea1b28a76aeba74744148b15099254d918671Owen Lin    public interface MenuItemsResult {
106666ea1b28a76aeba74744148b15099254d918671Owen Lin        public void gettingReadyToOpen(Menu menu, IImage image);
107666ea1b28a76aeba74744148b15099254d918671Owen Lin        public void aboutToCall(MenuItem item, IImage image);
108666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
109666ea1b28a76aeba74744148b15099254d918671Owen Lin
110666ea1b28a76aeba74744148b15099254d918671Owen Lin    public interface MenuInvoker {
111666ea1b28a76aeba74744148b15099254d918671Owen Lin        public void run(MenuCallback r);
112666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
113666ea1b28a76aeba74744148b15099254d918671Owen Lin
114666ea1b28a76aeba74744148b15099254d918671Owen Lin    public interface MenuCallback {
115666ea1b28a76aeba74744148b15099254d918671Owen Lin        public void run(Uri uri, IImage image);
116666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
117666ea1b28a76aeba74744148b15099254d918671Owen Lin
118666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static void closeSilently(Closeable c) {
119666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (c != null) {
120666ea1b28a76aeba74744148b15099254d918671Owen Lin            try {
121666ea1b28a76aeba74744148b15099254d918671Owen Lin                c.close();
122666ea1b28a76aeba74744148b15099254d918671Owen Lin            } catch (Throwable e) {
123666ea1b28a76aeba74744148b15099254d918671Owen Lin                // ignore
124666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
125666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
126666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
127666ea1b28a76aeba74744148b15099254d918671Owen Lin
128666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static long getImageFileSize(IImage image) {
129666ea1b28a76aeba74744148b15099254d918671Owen Lin        java.io.InputStream data = image.fullSizeImageData();
130666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (data == null) return -1;
131666ea1b28a76aeba74744148b15099254d918671Owen Lin        try {
132666ea1b28a76aeba74744148b15099254d918671Owen Lin            return data.available();
133666ea1b28a76aeba74744148b15099254d918671Owen Lin        } catch (java.io.IOException ex) {
134666ea1b28a76aeba74744148b15099254d918671Owen Lin            return -1;
135666ea1b28a76aeba74744148b15099254d918671Owen Lin        } finally {
136666ea1b28a76aeba74744148b15099254d918671Owen Lin            closeSilently(data);
137666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
138666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
139666ea1b28a76aeba74744148b15099254d918671Owen Lin
140666ea1b28a76aeba74744148b15099254d918671Owen Lin    // This is a hack before we find a solution to pass a permission to other
141666ea1b28a76aeba74744148b15099254d918671Owen Lin    // applications. See bug #1735149, #1836138.
142666ea1b28a76aeba74744148b15099254d918671Owen Lin    // Checks if the URI is on our whitelist:
143666ea1b28a76aeba74744148b15099254d918671Owen Lin    // content://media/... (MediaProvider)
144666ea1b28a76aeba74744148b15099254d918671Owen Lin    // file:///sdcard/... (Browser download)
145666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static boolean isWhiteListUri(Uri uri) {
146666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (uri == null) return false;
147666ea1b28a76aeba74744148b15099254d918671Owen Lin
148666ea1b28a76aeba74744148b15099254d918671Owen Lin        String scheme = uri.getScheme();
149666ea1b28a76aeba74744148b15099254d918671Owen Lin        String authority = uri.getAuthority();
150666ea1b28a76aeba74744148b15099254d918671Owen Lin
151666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (scheme.equals("content") && authority.equals("media")) {
152666ea1b28a76aeba74744148b15099254d918671Owen Lin            return true;
153666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
154666ea1b28a76aeba74744148b15099254d918671Owen Lin
155666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (scheme.equals("file")) {
156666ea1b28a76aeba74744148b15099254d918671Owen Lin            List<String> p = uri.getPathSegments();
157666ea1b28a76aeba74744148b15099254d918671Owen Lin
158666ea1b28a76aeba74744148b15099254d918671Owen Lin            if (p.size() >= 1 && p.get(0).equals("sdcard")) {
159666ea1b28a76aeba74744148b15099254d918671Owen Lin                return true;
160666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
161666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
162666ea1b28a76aeba74744148b15099254d918671Owen Lin
163666ea1b28a76aeba74744148b15099254d918671Owen Lin        return false;
164666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
165666ea1b28a76aeba74744148b15099254d918671Owen Lin
166666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static void enableShareMenuItem(Menu menu, boolean enabled) {
167666ea1b28a76aeba74744148b15099254d918671Owen Lin        MenuItem item = menu.findItem(MENU_IMAGE_SHARE);
168666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (item != null) {
169666ea1b28a76aeba74744148b15099254d918671Owen Lin            item.setVisible(enabled);
170666ea1b28a76aeba74744148b15099254d918671Owen Lin            item.setEnabled(enabled);
171666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
172666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
173666ea1b28a76aeba74744148b15099254d918671Owen Lin
174666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static boolean hasLatLngData(IImage image) {
175666ea1b28a76aeba74744148b15099254d918671Owen Lin        ExifInterface exif = getExif(image);
176666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (exif == null) return false;
177666ea1b28a76aeba74744148b15099254d918671Owen Lin        float latlng[] = new float[2];
178666ea1b28a76aeba74744148b15099254d918671Owen Lin        return exif.getLatLong(latlng);
179666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
180666ea1b28a76aeba74744148b15099254d918671Owen Lin
181666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static void enableShowOnMapMenuItem(Menu menu, boolean enabled) {
182666ea1b28a76aeba74744148b15099254d918671Owen Lin        MenuItem item = menu.findItem(MENU_IMAGE_SHOWMAP);
183666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (item != null) {
184666ea1b28a76aeba74744148b15099254d918671Owen Lin            item.setEnabled(enabled);
185666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
186666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
187666ea1b28a76aeba74744148b15099254d918671Owen Lin
188666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static void setDetailsValue(View d, String text, int valueId) {
189666ea1b28a76aeba74744148b15099254d918671Owen Lin        ((TextView) d.findViewById(valueId)).setText(text);
190666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
191666ea1b28a76aeba74744148b15099254d918671Owen Lin
192666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static void hideDetailsRow(View d, int rowId) {
193666ea1b28a76aeba74744148b15099254d918671Owen Lin        d.findViewById(rowId).setVisibility(View.GONE);
194666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
195666ea1b28a76aeba74744148b15099254d918671Owen Lin
196666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static class UpdateLocationCallback implements
197666ea1b28a76aeba74744148b15099254d918671Owen Lin            ReverseGeocoderTask.Callback {
198666ea1b28a76aeba74744148b15099254d918671Owen Lin        WeakReference<View> mView;
199666ea1b28a76aeba74744148b15099254d918671Owen Lin
200666ea1b28a76aeba74744148b15099254d918671Owen Lin        public UpdateLocationCallback(WeakReference<View> view) {
201666ea1b28a76aeba74744148b15099254d918671Owen Lin            mView = view;
202666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
203666ea1b28a76aeba74744148b15099254d918671Owen Lin
204666ea1b28a76aeba74744148b15099254d918671Owen Lin        public void onComplete(String location) {
205666ea1b28a76aeba74744148b15099254d918671Owen Lin            // View d is per-thread data, so when setDetailsValue is
206666ea1b28a76aeba74744148b15099254d918671Owen Lin            // executed by UI thread, it doesn't matter whether the
207666ea1b28a76aeba74744148b15099254d918671Owen Lin            // details dialog is dismissed or not.
208666ea1b28a76aeba74744148b15099254d918671Owen Lin            View view = mView.get();
209666ea1b28a76aeba74744148b15099254d918671Owen Lin            if (view == null) return;
210666ea1b28a76aeba74744148b15099254d918671Owen Lin            if (!location.equals(MenuHelper.EMPTY_STRING)) {
211666ea1b28a76aeba74744148b15099254d918671Owen Lin                MenuHelper.setDetailsValue(view, location,
212666ea1b28a76aeba74744148b15099254d918671Owen Lin                        R.id.details_location_value);
213666ea1b28a76aeba74744148b15099254d918671Owen Lin            } else {
214666ea1b28a76aeba74744148b15099254d918671Owen Lin                MenuHelper.hideDetailsRow(view, R.id.details_location_row);
215666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
216666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
217666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
218666ea1b28a76aeba74744148b15099254d918671Owen Lin
219666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static void setLatLngDetails(final View d, Activity context,
220666ea1b28a76aeba74744148b15099254d918671Owen Lin            ExifInterface exif) {
221666ea1b28a76aeba74744148b15099254d918671Owen Lin        float[] latlng = new float[2];
222666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (exif.getLatLong(latlng)) {
223666ea1b28a76aeba74744148b15099254d918671Owen Lin            setDetailsValue(d, String.valueOf(latlng[0]),
224666ea1b28a76aeba74744148b15099254d918671Owen Lin                    R.id.details_latitude_value);
225666ea1b28a76aeba74744148b15099254d918671Owen Lin            setDetailsValue(d, String.valueOf(latlng[1]),
226666ea1b28a76aeba74744148b15099254d918671Owen Lin                    R.id.details_longitude_value);
227666ea1b28a76aeba74744148b15099254d918671Owen Lin
228666ea1b28a76aeba74744148b15099254d918671Owen Lin            if (latlng[0] == INVALID_LATLNG || latlng[1] == INVALID_LATLNG) {
229666ea1b28a76aeba74744148b15099254d918671Owen Lin                hideDetailsRow(d, R.id.details_latitude_row);
230666ea1b28a76aeba74744148b15099254d918671Owen Lin                hideDetailsRow(d, R.id.details_longitude_row);
231666ea1b28a76aeba74744148b15099254d918671Owen Lin                hideDetailsRow(d, R.id.details_location_row);
232666ea1b28a76aeba74744148b15099254d918671Owen Lin                return;
233666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
234666ea1b28a76aeba74744148b15099254d918671Owen Lin
235666ea1b28a76aeba74744148b15099254d918671Owen Lin            UpdateLocationCallback cb = new UpdateLocationCallback(
236666ea1b28a76aeba74744148b15099254d918671Owen Lin                    new WeakReference<View>(d));
237666ea1b28a76aeba74744148b15099254d918671Owen Lin            Geocoder geocoder = new Geocoder(context);
238666ea1b28a76aeba74744148b15099254d918671Owen Lin            new ReverseGeocoderTask(geocoder, latlng, cb).execute();
239666ea1b28a76aeba74744148b15099254d918671Owen Lin        } else {
240666ea1b28a76aeba74744148b15099254d918671Owen Lin            hideDetailsRow(d, R.id.details_latitude_row);
241666ea1b28a76aeba74744148b15099254d918671Owen Lin            hideDetailsRow(d, R.id.details_longitude_row);
242666ea1b28a76aeba74744148b15099254d918671Owen Lin            hideDetailsRow(d, R.id.details_location_row);
243666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
244666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
245666ea1b28a76aeba74744148b15099254d918671Owen Lin
246666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static ExifInterface getExif(IImage image) {
247666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (!JPEG_MIME_TYPE.equals(image.getMimeType())) {
248666ea1b28a76aeba74744148b15099254d918671Owen Lin            return null;
249666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
250666ea1b28a76aeba74744148b15099254d918671Owen Lin
251666ea1b28a76aeba74744148b15099254d918671Owen Lin        try {
252666ea1b28a76aeba74744148b15099254d918671Owen Lin            return new ExifInterface(image.getDataPath());
253666ea1b28a76aeba74744148b15099254d918671Owen Lin        } catch (IOException ex) {
254666ea1b28a76aeba74744148b15099254d918671Owen Lin            Log.e(TAG, "cannot read exif", ex);
255666ea1b28a76aeba74744148b15099254d918671Owen Lin            return null;
256666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
257666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
258666ea1b28a76aeba74744148b15099254d918671Owen Lin    // Called when "Show on Maps" is clicked.
259666ea1b28a76aeba74744148b15099254d918671Owen Lin    // Displays image location on Google Maps for further operations.
260666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static boolean onShowMapClicked(MenuInvoker onInvoke,
261666ea1b28a76aeba74744148b15099254d918671Owen Lin                                            final Handler handler,
262666ea1b28a76aeba74744148b15099254d918671Owen Lin                                            final Activity activity) {
263666ea1b28a76aeba74744148b15099254d918671Owen Lin        onInvoke.run(new MenuCallback() {
264666ea1b28a76aeba74744148b15099254d918671Owen Lin            public void run(Uri u, IImage image) {
265666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (image == null) {
266666ea1b28a76aeba74744148b15099254d918671Owen Lin                    return;
267666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
268666ea1b28a76aeba74744148b15099254d918671Owen Lin
269666ea1b28a76aeba74744148b15099254d918671Owen Lin                boolean ok = false;
270666ea1b28a76aeba74744148b15099254d918671Owen Lin                ExifInterface exif = getExif(image);
271666ea1b28a76aeba74744148b15099254d918671Owen Lin                float latlng[] = null;
272666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (exif != null) {
273666ea1b28a76aeba74744148b15099254d918671Owen Lin                    latlng = new float[2];
274666ea1b28a76aeba74744148b15099254d918671Owen Lin                    if (exif.getLatLong(latlng)) {
275666ea1b28a76aeba74744148b15099254d918671Owen Lin                        ok = true;
276666ea1b28a76aeba74744148b15099254d918671Owen Lin                    }
277666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
278666ea1b28a76aeba74744148b15099254d918671Owen Lin
279666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (!ok) {
280666ea1b28a76aeba74744148b15099254d918671Owen Lin                    handler.post(new Runnable() {
281666ea1b28a76aeba74744148b15099254d918671Owen Lin                        public void run() {
282666ea1b28a76aeba74744148b15099254d918671Owen Lin                            Toast.makeText(activity,
283666ea1b28a76aeba74744148b15099254d918671Owen Lin                                    R.string.no_location_image,
284666ea1b28a76aeba74744148b15099254d918671Owen Lin                                    Toast.LENGTH_SHORT).show();
285666ea1b28a76aeba74744148b15099254d918671Owen Lin                        }
286666ea1b28a76aeba74744148b15099254d918671Owen Lin                    });
287666ea1b28a76aeba74744148b15099254d918671Owen Lin                    return;
288666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
289666ea1b28a76aeba74744148b15099254d918671Owen Lin
290666ea1b28a76aeba74744148b15099254d918671Owen Lin                // Can't use geo:latitude,longitude because it only centers
291666ea1b28a76aeba74744148b15099254d918671Owen Lin                // the MapView to specified location, but we need a bubble
292666ea1b28a76aeba74744148b15099254d918671Owen Lin                // for further operations (routing to/from).
293666ea1b28a76aeba74744148b15099254d918671Owen Lin                // The q=(lat, lng) syntax is suggested by geo-team.
294666ea1b28a76aeba74744148b15099254d918671Owen Lin                String uri = "http://maps.google.com/maps?f=q&" +
295666ea1b28a76aeba74744148b15099254d918671Owen Lin                        "q=(" + latlng[0] + "," + latlng[1] + ")";
296666ea1b28a76aeba74744148b15099254d918671Owen Lin                activity.startActivity(new Intent(
297666ea1b28a76aeba74744148b15099254d918671Owen Lin                        android.content.Intent.ACTION_VIEW,
298666ea1b28a76aeba74744148b15099254d918671Owen Lin                        Uri.parse(uri)));
299666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
300666ea1b28a76aeba74744148b15099254d918671Owen Lin        });
301666ea1b28a76aeba74744148b15099254d918671Owen Lin        return true;
302666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
303666ea1b28a76aeba74744148b15099254d918671Owen Lin
304666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static void hideExifInformation(View d) {
305666ea1b28a76aeba74744148b15099254d918671Owen Lin        hideDetailsRow(d, R.id.details_resolution_row);
306666ea1b28a76aeba74744148b15099254d918671Owen Lin        hideDetailsRow(d, R.id.details_make_row);
307666ea1b28a76aeba74744148b15099254d918671Owen Lin        hideDetailsRow(d, R.id.details_model_row);
308666ea1b28a76aeba74744148b15099254d918671Owen Lin        hideDetailsRow(d, R.id.details_whitebalance_row);
309666ea1b28a76aeba74744148b15099254d918671Owen Lin        hideDetailsRow(d, R.id.details_latitude_row);
310666ea1b28a76aeba74744148b15099254d918671Owen Lin        hideDetailsRow(d, R.id.details_longitude_row);
311666ea1b28a76aeba74744148b15099254d918671Owen Lin        hideDetailsRow(d, R.id.details_location_row);
312666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
313666ea1b28a76aeba74744148b15099254d918671Owen Lin
314666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static void showExifInformation(IImage image, View d,
315666ea1b28a76aeba74744148b15099254d918671Owen Lin            Activity activity) {
316666ea1b28a76aeba74744148b15099254d918671Owen Lin        ExifInterface exif = getExif(image);
317666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (exif == null) {
318666ea1b28a76aeba74744148b15099254d918671Owen Lin            hideExifInformation(d);
319666ea1b28a76aeba74744148b15099254d918671Owen Lin            return;
320666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
321666ea1b28a76aeba74744148b15099254d918671Owen Lin
322666ea1b28a76aeba74744148b15099254d918671Owen Lin        String value = exif.getAttribute(ExifInterface.TAG_MAKE);
323666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (value != null) {
324666ea1b28a76aeba74744148b15099254d918671Owen Lin            setDetailsValue(d, value, R.id.details_make_value);
325666ea1b28a76aeba74744148b15099254d918671Owen Lin        } else {
326666ea1b28a76aeba74744148b15099254d918671Owen Lin            hideDetailsRow(d, R.id.details_make_row);
327666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
328666ea1b28a76aeba74744148b15099254d918671Owen Lin
329666ea1b28a76aeba74744148b15099254d918671Owen Lin        value = exif.getAttribute(ExifInterface.TAG_MODEL);
330666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (value != null) {
331666ea1b28a76aeba74744148b15099254d918671Owen Lin            setDetailsValue(d, value, R.id.details_model_value);
332666ea1b28a76aeba74744148b15099254d918671Owen Lin        } else {
333666ea1b28a76aeba74744148b15099254d918671Owen Lin            hideDetailsRow(d, R.id.details_model_row);
334666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
335666ea1b28a76aeba74744148b15099254d918671Owen Lin
336666ea1b28a76aeba74744148b15099254d918671Owen Lin        value = getWhiteBalanceString(exif);
337666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (value != null && !value.equals(EMPTY_STRING)) {
338666ea1b28a76aeba74744148b15099254d918671Owen Lin            setDetailsValue(d, value, R.id.details_whitebalance_value);
339666ea1b28a76aeba74744148b15099254d918671Owen Lin        } else {
340666ea1b28a76aeba74744148b15099254d918671Owen Lin            hideDetailsRow(d, R.id.details_whitebalance_row);
341666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
342666ea1b28a76aeba74744148b15099254d918671Owen Lin
343666ea1b28a76aeba74744148b15099254d918671Owen Lin        setLatLngDetails(d, activity, exif);
344666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
345666ea1b28a76aeba74744148b15099254d918671Owen Lin
346666ea1b28a76aeba74744148b15099254d918671Owen Lin    /**
347666ea1b28a76aeba74744148b15099254d918671Owen Lin     * Returns a human-readable string describing the white balance value. Returns empty
348666ea1b28a76aeba74744148b15099254d918671Owen Lin     * string if there is no white balance value or it is not recognized.
349666ea1b28a76aeba74744148b15099254d918671Owen Lin     */
350666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static String getWhiteBalanceString(ExifInterface exif) {
351666ea1b28a76aeba74744148b15099254d918671Owen Lin        int whitebalance = exif.getAttributeInt(ExifInterface.TAG_WHITE_BALANCE, -1);
352666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (whitebalance == -1) return "";
353666ea1b28a76aeba74744148b15099254d918671Owen Lin
354666ea1b28a76aeba74744148b15099254d918671Owen Lin        switch (whitebalance) {
355666ea1b28a76aeba74744148b15099254d918671Owen Lin            case ExifInterface.WHITEBALANCE_AUTO:
356666ea1b28a76aeba74744148b15099254d918671Owen Lin                return "Auto";
357666ea1b28a76aeba74744148b15099254d918671Owen Lin            case ExifInterface.WHITEBALANCE_MANUAL:
358666ea1b28a76aeba74744148b15099254d918671Owen Lin                return "Manual";
359666ea1b28a76aeba74744148b15099254d918671Owen Lin            default:
360666ea1b28a76aeba74744148b15099254d918671Owen Lin                return "";
361666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
362666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
363666ea1b28a76aeba74744148b15099254d918671Owen Lin
364666ea1b28a76aeba74744148b15099254d918671Owen Lin    // Called when "Details" is clicked.
365666ea1b28a76aeba74744148b15099254d918671Owen Lin    // Displays detailed information about the image/video.
366666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static boolean onDetailsClicked(MenuInvoker onInvoke,
367666ea1b28a76aeba74744148b15099254d918671Owen Lin                                            final Handler handler,
368666ea1b28a76aeba74744148b15099254d918671Owen Lin                                            final Activity activity) {
369666ea1b28a76aeba74744148b15099254d918671Owen Lin        onInvoke.run(new MenuCallback() {
370666ea1b28a76aeba74744148b15099254d918671Owen Lin            public void run(Uri u, IImage image) {
371666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (image == null) {
372666ea1b28a76aeba74744148b15099254d918671Owen Lin                    return;
373666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
374666ea1b28a76aeba74744148b15099254d918671Owen Lin
375666ea1b28a76aeba74744148b15099254d918671Owen Lin                final AlertDialog.Builder builder =
376666ea1b28a76aeba74744148b15099254d918671Owen Lin                        new AlertDialog.Builder(activity);
377666ea1b28a76aeba74744148b15099254d918671Owen Lin
378666ea1b28a76aeba74744148b15099254d918671Owen Lin                final View d = View.inflate(activity, R.layout.detailsview,
379666ea1b28a76aeba74744148b15099254d918671Owen Lin                        null);
380666ea1b28a76aeba74744148b15099254d918671Owen Lin
381666ea1b28a76aeba74744148b15099254d918671Owen Lin                ImageView imageView = (ImageView) d.findViewById(
382666ea1b28a76aeba74744148b15099254d918671Owen Lin                        R.id.details_thumbnail_image);
383666ea1b28a76aeba74744148b15099254d918671Owen Lin                imageView.setImageBitmap(image.miniThumbBitmap());
384666ea1b28a76aeba74744148b15099254d918671Owen Lin
385666ea1b28a76aeba74744148b15099254d918671Owen Lin                TextView textView = (TextView) d.findViewById(
386666ea1b28a76aeba74744148b15099254d918671Owen Lin                        R.id.details_image_title);
387185a1a7c5f33ecc5cb9a36d23cecb719c8727178Chih-Chung Chang                textView.setText(image.getTitle());
388666ea1b28a76aeba74744148b15099254d918671Owen Lin
389666ea1b28a76aeba74744148b15099254d918671Owen Lin                long length = getImageFileSize(image);
390666ea1b28a76aeba74744148b15099254d918671Owen Lin                String lengthString = length < 0
391666ea1b28a76aeba74744148b15099254d918671Owen Lin                        ? EMPTY_STRING
392666ea1b28a76aeba74744148b15099254d918671Owen Lin                        : Formatter.formatFileSize(activity, length);
393666ea1b28a76aeba74744148b15099254d918671Owen Lin                ((TextView) d
394666ea1b28a76aeba74744148b15099254d918671Owen Lin                    .findViewById(R.id.details_file_size_value))
395666ea1b28a76aeba74744148b15099254d918671Owen Lin                    .setText(lengthString);
396666ea1b28a76aeba74744148b15099254d918671Owen Lin
397e2491be44bb894d2c11e5836c8c399811edc074cJames Dong                d.findViewById(R.id.details_frame_rate_row)
398e2491be44bb894d2c11e5836c8c399811edc074cJames Dong                            .setVisibility(View.GONE);
399e2491be44bb894d2c11e5836c8c399811edc074cJames Dong                d.findViewById(R.id.details_bit_rate_row)
400e2491be44bb894d2c11e5836c8c399811edc074cJames Dong                            .setVisibility(View.GONE);
401e2491be44bb894d2c11e5836c8c399811edc074cJames Dong                d.findViewById(R.id.details_format_row)
402e2491be44bb894d2c11e5836c8c399811edc074cJames Dong                            .setVisibility(View.GONE);
403e2491be44bb894d2c11e5836c8c399811edc074cJames Dong                d.findViewById(R.id.details_codec_row)
404e2491be44bb894d2c11e5836c8c399811edc074cJames Dong                            .setVisibility(View.GONE);
405e2491be44bb894d2c11e5836c8c399811edc074cJames Dong
406666ea1b28a76aeba74744148b15099254d918671Owen Lin                int dimensionWidth = 0;
407666ea1b28a76aeba74744148b15099254d918671Owen Lin                int dimensionHeight = 0;
408666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (ImageManager.isImage(image)) {
409666ea1b28a76aeba74744148b15099254d918671Owen Lin                    // getWidth is much slower than reading from EXIF
410666ea1b28a76aeba74744148b15099254d918671Owen Lin                    dimensionWidth = image.getWidth();
411666ea1b28a76aeba74744148b15099254d918671Owen Lin                    dimensionHeight = image.getHeight();
412666ea1b28a76aeba74744148b15099254d918671Owen Lin                    d.findViewById(R.id.details_duration_row)
413666ea1b28a76aeba74744148b15099254d918671Owen Lin                            .setVisibility(View.GONE);
414666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
415666ea1b28a76aeba74744148b15099254d918671Owen Lin
416666ea1b28a76aeba74744148b15099254d918671Owen Lin                String value = null;
417666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (dimensionWidth > 0 && dimensionHeight > 0) {
418666ea1b28a76aeba74744148b15099254d918671Owen Lin                    value = String.format(
419666ea1b28a76aeba74744148b15099254d918671Owen Lin                            activity.getString(R.string.details_dimension_x),
420666ea1b28a76aeba74744148b15099254d918671Owen Lin                            dimensionWidth, dimensionHeight);
421666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
422666ea1b28a76aeba74744148b15099254d918671Owen Lin
423666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (value != null) {
424666ea1b28a76aeba74744148b15099254d918671Owen Lin                    setDetailsValue(d, value, R.id.details_resolution_value);
425666ea1b28a76aeba74744148b15099254d918671Owen Lin                } else {
426666ea1b28a76aeba74744148b15099254d918671Owen Lin                    hideDetailsRow(d, R.id.details_resolution_row);
427666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
428666ea1b28a76aeba74744148b15099254d918671Owen Lin
429666ea1b28a76aeba74744148b15099254d918671Owen Lin                value = EMPTY_STRING;
430666ea1b28a76aeba74744148b15099254d918671Owen Lin                long dateTaken = image.getDateTaken();
431666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (dateTaken != 0) {
432666ea1b28a76aeba74744148b15099254d918671Owen Lin                    Date date = new Date(image.getDateTaken());
433666ea1b28a76aeba74744148b15099254d918671Owen Lin                    SimpleDateFormat dateFormat = new SimpleDateFormat();
434666ea1b28a76aeba74744148b15099254d918671Owen Lin                    value = dateFormat.format(date);
435666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
436666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (value != EMPTY_STRING) {
437666ea1b28a76aeba74744148b15099254d918671Owen Lin                    setDetailsValue(d, value, R.id.details_date_taken_value);
438666ea1b28a76aeba74744148b15099254d918671Owen Lin                } else {
439666ea1b28a76aeba74744148b15099254d918671Owen Lin                    hideDetailsRow(d, R.id.details_date_taken_row);
440666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
441666ea1b28a76aeba74744148b15099254d918671Owen Lin
442666ea1b28a76aeba74744148b15099254d918671Owen Lin                // Show more EXIF header details for JPEG images.
443666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (JPEG_MIME_TYPE.equals(image.getMimeType())) {
444666ea1b28a76aeba74744148b15099254d918671Owen Lin                    showExifInformation(image, d, activity);
445666ea1b28a76aeba74744148b15099254d918671Owen Lin                } else {
446666ea1b28a76aeba74744148b15099254d918671Owen Lin                    hideExifInformation(d);
447666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
448666ea1b28a76aeba74744148b15099254d918671Owen Lin
449666ea1b28a76aeba74744148b15099254d918671Owen Lin                builder.setNeutralButton(R.string.details_ok,
450666ea1b28a76aeba74744148b15099254d918671Owen Lin                        new DialogInterface.OnClickListener() {
451666ea1b28a76aeba74744148b15099254d918671Owen Lin                            public void onClick(DialogInterface dialog,
452666ea1b28a76aeba74744148b15099254d918671Owen Lin                                    int which) {
453666ea1b28a76aeba74744148b15099254d918671Owen Lin                                dialog.dismiss();
454666ea1b28a76aeba74744148b15099254d918671Owen Lin                            }
455666ea1b28a76aeba74744148b15099254d918671Owen Lin                        });
456666ea1b28a76aeba74744148b15099254d918671Owen Lin
457666ea1b28a76aeba74744148b15099254d918671Owen Lin                handler.post(
458666ea1b28a76aeba74744148b15099254d918671Owen Lin                        new Runnable() {
459666ea1b28a76aeba74744148b15099254d918671Owen Lin                            public void run() {
460666ea1b28a76aeba74744148b15099254d918671Owen Lin                                builder.setIcon(
461666ea1b28a76aeba74744148b15099254d918671Owen Lin                                        android.R.drawable.ic_dialog_info)
462666ea1b28a76aeba74744148b15099254d918671Owen Lin                                        .setTitle(R.string.details_panel_title)
463666ea1b28a76aeba74744148b15099254d918671Owen Lin                                        .setView(d)
464666ea1b28a76aeba74744148b15099254d918671Owen Lin                                        .show();
465666ea1b28a76aeba74744148b15099254d918671Owen Lin                            }
466666ea1b28a76aeba74744148b15099254d918671Owen Lin                        });
467666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
468666ea1b28a76aeba74744148b15099254d918671Owen Lin        });
469666ea1b28a76aeba74744148b15099254d918671Owen Lin        return true;
470666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
471666ea1b28a76aeba74744148b15099254d918671Owen Lin
472666ea1b28a76aeba74744148b15099254d918671Owen Lin    // Called when "Rotate left" or "Rotate right" is clicked.
473666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static boolean onRotateClicked(MenuInvoker onInvoke,
474666ea1b28a76aeba74744148b15099254d918671Owen Lin            final int degree) {
475666ea1b28a76aeba74744148b15099254d918671Owen Lin        onInvoke.run(new MenuCallback() {
476666ea1b28a76aeba74744148b15099254d918671Owen Lin            public void run(Uri u, IImage image) {
477666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (image == null || image.isReadonly()) {
478666ea1b28a76aeba74744148b15099254d918671Owen Lin                    return;
479666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
480666ea1b28a76aeba74744148b15099254d918671Owen Lin                image.rotateImageBy(degree);
481666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
482666ea1b28a76aeba74744148b15099254d918671Owen Lin        });
483666ea1b28a76aeba74744148b15099254d918671Owen Lin        return true;
484666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
485666ea1b28a76aeba74744148b15099254d918671Owen Lin
486666ea1b28a76aeba74744148b15099254d918671Owen Lin    // Called when "Crop" is clicked.
487666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static boolean onCropClicked(MenuInvoker onInvoke,
488666ea1b28a76aeba74744148b15099254d918671Owen Lin                                         final Activity activity) {
489666ea1b28a76aeba74744148b15099254d918671Owen Lin        onInvoke.run(new MenuCallback() {
490666ea1b28a76aeba74744148b15099254d918671Owen Lin            public void run(Uri u, IImage image) {
491666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (u == null) {
492666ea1b28a76aeba74744148b15099254d918671Owen Lin                    return;
493666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
494666ea1b28a76aeba74744148b15099254d918671Owen Lin
4958aa3fbcf9a5a0d11acd48861f5167073e3554980Owen Lin                Intent cropIntent = new Intent(
4968aa3fbcf9a5a0d11acd48861f5167073e3554980Owen Lin                        "com.android.camera.action.CROP");
497666ea1b28a76aeba74744148b15099254d918671Owen Lin                cropIntent.setData(u);
4988aa3fbcf9a5a0d11acd48861f5167073e3554980Owen Lin                activity.startActivityForResult(
4998aa3fbcf9a5a0d11acd48861f5167073e3554980Owen Lin                        cropIntent, RESULT_COMMON_MENU_CROP);
500666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
501666ea1b28a76aeba74744148b15099254d918671Owen Lin        });
502666ea1b28a76aeba74744148b15099254d918671Owen Lin        return true;
503666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
504666ea1b28a76aeba74744148b15099254d918671Owen Lin
505666ea1b28a76aeba74744148b15099254d918671Owen Lin    // Called when "Set as" is clicked.
506666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static boolean onSetAsClicked(MenuInvoker onInvoke,
507666ea1b28a76aeba74744148b15099254d918671Owen Lin                                          final Activity activity) {
508666ea1b28a76aeba74744148b15099254d918671Owen Lin        onInvoke.run(new MenuCallback() {
509666ea1b28a76aeba74744148b15099254d918671Owen Lin            public void run(Uri u, IImage image) {
510666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (u == null || image == null) {
511666ea1b28a76aeba74744148b15099254d918671Owen Lin                    return;
512666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
513666ea1b28a76aeba74744148b15099254d918671Owen Lin
514666ea1b28a76aeba74744148b15099254d918671Owen Lin                Intent intent = Util.createSetAsIntent(image);
515666ea1b28a76aeba74744148b15099254d918671Owen Lin                activity.startActivity(Intent.createChooser(intent,
516666ea1b28a76aeba74744148b15099254d918671Owen Lin                        activity.getText(R.string.setImage)));
517666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
518666ea1b28a76aeba74744148b15099254d918671Owen Lin        });
519666ea1b28a76aeba74744148b15099254d918671Owen Lin        return true;
520666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
521666ea1b28a76aeba74744148b15099254d918671Owen Lin
522666ea1b28a76aeba74744148b15099254d918671Owen Lin    // Called when "Share" is clicked.
523666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static boolean onImageShareClicked(MenuInvoker onInvoke,
524666ea1b28a76aeba74744148b15099254d918671Owen Lin            final Activity activity) {
525666ea1b28a76aeba74744148b15099254d918671Owen Lin        onInvoke.run(new MenuCallback() {
526666ea1b28a76aeba74744148b15099254d918671Owen Lin            public void run(Uri u, IImage image) {
527666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (image == null) return;
528666ea1b28a76aeba74744148b15099254d918671Owen Lin
529666ea1b28a76aeba74744148b15099254d918671Owen Lin                Intent intent = new Intent();
530666ea1b28a76aeba74744148b15099254d918671Owen Lin                intent.setAction(Intent.ACTION_SEND);
531666ea1b28a76aeba74744148b15099254d918671Owen Lin                String mimeType = image.getMimeType();
532666ea1b28a76aeba74744148b15099254d918671Owen Lin                intent.setType(mimeType);
533666ea1b28a76aeba74744148b15099254d918671Owen Lin                intent.putExtra(Intent.EXTRA_STREAM, u);
534666ea1b28a76aeba74744148b15099254d918671Owen Lin                boolean isImage = ImageManager.isImage(image);
535666ea1b28a76aeba74744148b15099254d918671Owen Lin                try {
536666ea1b28a76aeba74744148b15099254d918671Owen Lin                    activity.startActivity(Intent.createChooser(intent,
537666ea1b28a76aeba74744148b15099254d918671Owen Lin                            activity.getText(isImage
538666ea1b28a76aeba74744148b15099254d918671Owen Lin                            ? R.string.sendImage
539666ea1b28a76aeba74744148b15099254d918671Owen Lin                            : R.string.sendVideo)));
540666ea1b28a76aeba74744148b15099254d918671Owen Lin                } catch (android.content.ActivityNotFoundException ex) {
541666ea1b28a76aeba74744148b15099254d918671Owen Lin                    Toast.makeText(activity, isImage
542666ea1b28a76aeba74744148b15099254d918671Owen Lin                            ? R.string.no_way_to_share_image
543666ea1b28a76aeba74744148b15099254d918671Owen Lin                            : R.string.no_way_to_share_video,
544666ea1b28a76aeba74744148b15099254d918671Owen Lin                            Toast.LENGTH_SHORT).show();
545666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
546666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
547666ea1b28a76aeba74744148b15099254d918671Owen Lin        });
548666ea1b28a76aeba74744148b15099254d918671Owen Lin        return true;
549666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
550666ea1b28a76aeba74744148b15099254d918671Owen Lin
551666ea1b28a76aeba74744148b15099254d918671Owen Lin    // Called when "Play" is clicked.
552666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static boolean onViewPlayClicked(MenuInvoker onInvoke,
553666ea1b28a76aeba74744148b15099254d918671Owen Lin            final Activity activity) {
554666ea1b28a76aeba74744148b15099254d918671Owen Lin        onInvoke.run(new MenuCallback() {
555666ea1b28a76aeba74744148b15099254d918671Owen Lin            public void run(Uri uri, IImage image) {
556666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (image != null) {
557666ea1b28a76aeba74744148b15099254d918671Owen Lin                    Intent intent = new Intent(Intent.ACTION_VIEW,
558666ea1b28a76aeba74744148b15099254d918671Owen Lin                            image.fullSizeImageUri());
559666ea1b28a76aeba74744148b15099254d918671Owen Lin                    activity.startActivity(intent);
560666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
561666ea1b28a76aeba74744148b15099254d918671Owen Lin            }});
562666ea1b28a76aeba74744148b15099254d918671Owen Lin        return true;
563666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
564666ea1b28a76aeba74744148b15099254d918671Owen Lin
565666ea1b28a76aeba74744148b15099254d918671Owen Lin    // Called when "Delete" is clicked.
566666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static boolean onDeleteClicked(MenuInvoker onInvoke,
567666ea1b28a76aeba74744148b15099254d918671Owen Lin            final Activity activity, final Runnable onDelete) {
568666ea1b28a76aeba74744148b15099254d918671Owen Lin        onInvoke.run(new MenuCallback() {
569666ea1b28a76aeba74744148b15099254d918671Owen Lin            public void run(Uri uri, IImage image) {
570666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (image != null) {
571666ea1b28a76aeba74744148b15099254d918671Owen Lin                    deleteImage(activity, onDelete, image);
572666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
573666ea1b28a76aeba74744148b15099254d918671Owen Lin            }});
574666ea1b28a76aeba74744148b15099254d918671Owen Lin        return true;
575666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
576666ea1b28a76aeba74744148b15099254d918671Owen Lin
577666ea1b28a76aeba74744148b15099254d918671Owen Lin    static MenuItemsResult addImageMenuItems(
578666ea1b28a76aeba74744148b15099254d918671Owen Lin            Menu menu,
579666ea1b28a76aeba74744148b15099254d918671Owen Lin            int inclusions,
580666ea1b28a76aeba74744148b15099254d918671Owen Lin            final Activity activity,
581666ea1b28a76aeba74744148b15099254d918671Owen Lin            final Handler handler,
582666ea1b28a76aeba74744148b15099254d918671Owen Lin            final Runnable onDelete,
583666ea1b28a76aeba74744148b15099254d918671Owen Lin            final MenuInvoker onInvoke) {
584666ea1b28a76aeba74744148b15099254d918671Owen Lin        final ArrayList<MenuItem> requiresWriteAccessItems =
585666ea1b28a76aeba74744148b15099254d918671Owen Lin                new ArrayList<MenuItem>();
586666ea1b28a76aeba74744148b15099254d918671Owen Lin        final ArrayList<MenuItem> requiresNoDrmAccessItems =
587666ea1b28a76aeba74744148b15099254d918671Owen Lin                new ArrayList<MenuItem>();
588666ea1b28a76aeba74744148b15099254d918671Owen Lin        final ArrayList<MenuItem> requiresImageItems =
589666ea1b28a76aeba74744148b15099254d918671Owen Lin                new ArrayList<MenuItem>();
590666ea1b28a76aeba74744148b15099254d918671Owen Lin        final ArrayList<MenuItem> requiresVideoItems =
591666ea1b28a76aeba74744148b15099254d918671Owen Lin                new ArrayList<MenuItem>();
592666ea1b28a76aeba74744148b15099254d918671Owen Lin
593666ea1b28a76aeba74744148b15099254d918671Owen Lin        if ((inclusions & INCLUDE_ROTATE_MENU) != 0) {
594666ea1b28a76aeba74744148b15099254d918671Owen Lin            SubMenu rotateSubmenu = menu.addSubMenu(Menu.NONE, Menu.NONE,
595666ea1b28a76aeba74744148b15099254d918671Owen Lin                    POSITION_IMAGE_ROTATE, R.string.rotate)
596666ea1b28a76aeba74744148b15099254d918671Owen Lin                    .setIcon(android.R.drawable.ic_menu_rotate);
597666ea1b28a76aeba74744148b15099254d918671Owen Lin            // Don't show the rotate submenu if the item at hand is read only
598666ea1b28a76aeba74744148b15099254d918671Owen Lin            // since the items within the submenu won't be shown anyway. This
599666ea1b28a76aeba74744148b15099254d918671Owen Lin            // is really a framework bug in that it shouldn't show the submenu
600666ea1b28a76aeba74744148b15099254d918671Owen Lin            // if the submenu has no visible items.
601666ea1b28a76aeba74744148b15099254d918671Owen Lin            MenuItem rotateLeft = rotateSubmenu.add(R.string.rotate_left)
602666ea1b28a76aeba74744148b15099254d918671Owen Lin                    .setOnMenuItemClickListener(
603666ea1b28a76aeba74744148b15099254d918671Owen Lin                    new MenuItem.OnMenuItemClickListener() {
604666ea1b28a76aeba74744148b15099254d918671Owen Lin                        public boolean onMenuItemClick(MenuItem item) {
605666ea1b28a76aeba74744148b15099254d918671Owen Lin                            return onRotateClicked(onInvoke, -90);
606666ea1b28a76aeba74744148b15099254d918671Owen Lin                        }
607666ea1b28a76aeba74744148b15099254d918671Owen Lin                    }).setAlphabeticShortcut('l');
608666ea1b28a76aeba74744148b15099254d918671Owen Lin
609666ea1b28a76aeba74744148b15099254d918671Owen Lin            MenuItem rotateRight = rotateSubmenu.add(R.string.rotate_right)
610666ea1b28a76aeba74744148b15099254d918671Owen Lin                    .setOnMenuItemClickListener(
611666ea1b28a76aeba74744148b15099254d918671Owen Lin                    new MenuItem.OnMenuItemClickListener() {
612666ea1b28a76aeba74744148b15099254d918671Owen Lin                        public boolean onMenuItemClick(MenuItem item) {
613666ea1b28a76aeba74744148b15099254d918671Owen Lin                            return onRotateClicked(onInvoke, 90);
614666ea1b28a76aeba74744148b15099254d918671Owen Lin                        }
615666ea1b28a76aeba74744148b15099254d918671Owen Lin                    }).setAlphabeticShortcut('r');
616666ea1b28a76aeba74744148b15099254d918671Owen Lin
617666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresWriteAccessItems.add(rotateSubmenu.getItem());
618666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresWriteAccessItems.add(rotateLeft);
619666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresWriteAccessItems.add(rotateRight);
620666ea1b28a76aeba74744148b15099254d918671Owen Lin
621666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresImageItems.add(rotateSubmenu.getItem());
622666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresImageItems.add(rotateLeft);
623666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresImageItems.add(rotateRight);
624666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
625666ea1b28a76aeba74744148b15099254d918671Owen Lin
626666ea1b28a76aeba74744148b15099254d918671Owen Lin        if ((inclusions & INCLUDE_CROP_MENU) != 0) {
627666ea1b28a76aeba74744148b15099254d918671Owen Lin            MenuItem autoCrop = menu.add(Menu.NONE, Menu.NONE,
628666ea1b28a76aeba74744148b15099254d918671Owen Lin                    POSITION_IMAGE_CROP, R.string.camera_crop);
629666ea1b28a76aeba74744148b15099254d918671Owen Lin            autoCrop.setIcon(android.R.drawable.ic_menu_crop);
630666ea1b28a76aeba74744148b15099254d918671Owen Lin            autoCrop.setOnMenuItemClickListener(
631666ea1b28a76aeba74744148b15099254d918671Owen Lin                    new MenuItem.OnMenuItemClickListener() {
632666ea1b28a76aeba74744148b15099254d918671Owen Lin                        public boolean onMenuItemClick(MenuItem item) {
633666ea1b28a76aeba74744148b15099254d918671Owen Lin                            return onCropClicked(onInvoke, activity);
634666ea1b28a76aeba74744148b15099254d918671Owen Lin                        }
635666ea1b28a76aeba74744148b15099254d918671Owen Lin                    });
636666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresWriteAccessItems.add(autoCrop);
637666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresImageItems.add(autoCrop);
638666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
639666ea1b28a76aeba74744148b15099254d918671Owen Lin
640666ea1b28a76aeba74744148b15099254d918671Owen Lin        if ((inclusions & INCLUDE_SET_MENU) != 0) {
641666ea1b28a76aeba74744148b15099254d918671Owen Lin            MenuItem setMenu = menu.add(Menu.NONE, Menu.NONE,
642666ea1b28a76aeba74744148b15099254d918671Owen Lin                    POSITION_IMAGE_SET, R.string.camera_set);
643666ea1b28a76aeba74744148b15099254d918671Owen Lin            setMenu.setIcon(android.R.drawable.ic_menu_set_as);
644666ea1b28a76aeba74744148b15099254d918671Owen Lin            setMenu.setOnMenuItemClickListener(
645666ea1b28a76aeba74744148b15099254d918671Owen Lin                    new MenuItem.OnMenuItemClickListener() {
646666ea1b28a76aeba74744148b15099254d918671Owen Lin                        public boolean onMenuItemClick(MenuItem item) {
647666ea1b28a76aeba74744148b15099254d918671Owen Lin                            return onSetAsClicked(onInvoke, activity);
648666ea1b28a76aeba74744148b15099254d918671Owen Lin                        }
649666ea1b28a76aeba74744148b15099254d918671Owen Lin                    });
650666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresImageItems.add(setMenu);
651666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
652666ea1b28a76aeba74744148b15099254d918671Owen Lin
653666ea1b28a76aeba74744148b15099254d918671Owen Lin        if ((inclusions & INCLUDE_SHARE_MENU) != 0) {
654666ea1b28a76aeba74744148b15099254d918671Owen Lin            MenuItem item1 = menu.add(Menu.NONE, MENU_IMAGE_SHARE,
655666ea1b28a76aeba74744148b15099254d918671Owen Lin                    POSITION_IMAGE_SHARE, R.string.camera_share)
656666ea1b28a76aeba74744148b15099254d918671Owen Lin                    .setOnMenuItemClickListener(
657666ea1b28a76aeba74744148b15099254d918671Owen Lin                    new MenuItem.OnMenuItemClickListener() {
658666ea1b28a76aeba74744148b15099254d918671Owen Lin                        public boolean onMenuItemClick(MenuItem item) {
659666ea1b28a76aeba74744148b15099254d918671Owen Lin                            return onImageShareClicked(onInvoke, activity);
660666ea1b28a76aeba74744148b15099254d918671Owen Lin                        }
661666ea1b28a76aeba74744148b15099254d918671Owen Lin                    });
662666ea1b28a76aeba74744148b15099254d918671Owen Lin            item1.setIcon(android.R.drawable.ic_menu_share);
663666ea1b28a76aeba74744148b15099254d918671Owen Lin            MenuItem item = item1;
664666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresNoDrmAccessItems.add(item);
665666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
666666ea1b28a76aeba74744148b15099254d918671Owen Lin
667666ea1b28a76aeba74744148b15099254d918671Owen Lin        if ((inclusions & INCLUDE_DELETE_MENU) != 0) {
668666ea1b28a76aeba74744148b15099254d918671Owen Lin            MenuItem deleteItem = menu.add(Menu.NONE, Menu.NONE,
669666ea1b28a76aeba74744148b15099254d918671Owen Lin                    POSITION_IMAGE_TOSS, R.string.camera_toss);
670666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresWriteAccessItems.add(deleteItem);
671666ea1b28a76aeba74744148b15099254d918671Owen Lin            deleteItem.setOnMenuItemClickListener(
672666ea1b28a76aeba74744148b15099254d918671Owen Lin                    new MenuItem.OnMenuItemClickListener() {
673666ea1b28a76aeba74744148b15099254d918671Owen Lin                        public boolean onMenuItemClick(MenuItem item) {
674666ea1b28a76aeba74744148b15099254d918671Owen Lin                            return onDeleteClicked(onInvoke, activity,
675666ea1b28a76aeba74744148b15099254d918671Owen Lin                                    onDelete);
676666ea1b28a76aeba74744148b15099254d918671Owen Lin                        }
677666ea1b28a76aeba74744148b15099254d918671Owen Lin                    })
678666ea1b28a76aeba74744148b15099254d918671Owen Lin                    .setAlphabeticShortcut('d')
679666ea1b28a76aeba74744148b15099254d918671Owen Lin                    .setIcon(android.R.drawable.ic_menu_delete);
680666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
681666ea1b28a76aeba74744148b15099254d918671Owen Lin
682666ea1b28a76aeba74744148b15099254d918671Owen Lin        if ((inclusions & INCLUDE_DETAILS_MENU) != 0) {
683666ea1b28a76aeba74744148b15099254d918671Owen Lin            MenuItem detailsMenu = menu.add(Menu.NONE, Menu.NONE,
684666ea1b28a76aeba74744148b15099254d918671Owen Lin                POSITION_DETAILS, R.string.details)
685666ea1b28a76aeba74744148b15099254d918671Owen Lin            .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
686666ea1b28a76aeba74744148b15099254d918671Owen Lin                public boolean onMenuItemClick(MenuItem item) {
687666ea1b28a76aeba74744148b15099254d918671Owen Lin                    return onDetailsClicked(onInvoke, handler, activity);
688666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
689666ea1b28a76aeba74744148b15099254d918671Owen Lin            });
690666ea1b28a76aeba74744148b15099254d918671Owen Lin            detailsMenu.setIcon(R.drawable.ic_menu_view_details);
691666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
692666ea1b28a76aeba74744148b15099254d918671Owen Lin
693666ea1b28a76aeba74744148b15099254d918671Owen Lin        if ((inclusions & INCLUDE_SHOWMAP_MENU) != 0) {
694666ea1b28a76aeba74744148b15099254d918671Owen Lin            MenuItem showOnMapItem = menu.add(Menu.NONE, MENU_IMAGE_SHOWMAP,
695666ea1b28a76aeba74744148b15099254d918671Owen Lin                    POSITION_SHOWMAP, R.string.show_on_map);
696666ea1b28a76aeba74744148b15099254d918671Owen Lin            showOnMapItem.setOnMenuItemClickListener(
697666ea1b28a76aeba74744148b15099254d918671Owen Lin                        new MenuItem.OnMenuItemClickListener() {
698666ea1b28a76aeba74744148b15099254d918671Owen Lin                            public boolean onMenuItemClick(MenuItem item) {
699666ea1b28a76aeba74744148b15099254d918671Owen Lin                                return onShowMapClicked(onInvoke,
700666ea1b28a76aeba74744148b15099254d918671Owen Lin                                        handler, activity);
701666ea1b28a76aeba74744148b15099254d918671Owen Lin                            }
702666ea1b28a76aeba74744148b15099254d918671Owen Lin                        }).setIcon(R.drawable.ic_menu_3d_globe);
703666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresImageItems.add(showOnMapItem);
704666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
705666ea1b28a76aeba74744148b15099254d918671Owen Lin
706666ea1b28a76aeba74744148b15099254d918671Owen Lin        if ((inclusions & INCLUDE_VIEWPLAY_MENU) != 0) {
707666ea1b28a76aeba74744148b15099254d918671Owen Lin            MenuItem videoPlayItem = menu.add(Menu.NONE, Menu.NONE,
708666ea1b28a76aeba74744148b15099254d918671Owen Lin                POSITION_VIEWPLAY, R.string.video_play)
709666ea1b28a76aeba74744148b15099254d918671Owen Lin                .setOnMenuItemClickListener(
710666ea1b28a76aeba74744148b15099254d918671Owen Lin                new MenuItem.OnMenuItemClickListener() {
711666ea1b28a76aeba74744148b15099254d918671Owen Lin                public boolean onMenuItemClick(MenuItem item) {
712666ea1b28a76aeba74744148b15099254d918671Owen Lin                    return onViewPlayClicked(onInvoke, activity);
713666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
714666ea1b28a76aeba74744148b15099254d918671Owen Lin            });
715666ea1b28a76aeba74744148b15099254d918671Owen Lin            videoPlayItem.setIcon(
716666ea1b28a76aeba74744148b15099254d918671Owen Lin                    com.android.internal.R.drawable.ic_menu_play_clip);
717666ea1b28a76aeba74744148b15099254d918671Owen Lin            requiresVideoItems.add(videoPlayItem);
718666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
719666ea1b28a76aeba74744148b15099254d918671Owen Lin
720666ea1b28a76aeba74744148b15099254d918671Owen Lin        return new MenuItemsResult() {
721666ea1b28a76aeba74744148b15099254d918671Owen Lin            public void gettingReadyToOpen(Menu menu, IImage image) {
722666ea1b28a76aeba74744148b15099254d918671Owen Lin                // protect against null here.  this isn't strictly speaking
723666ea1b28a76aeba74744148b15099254d918671Owen Lin                // required but if a client app isn't handling sdcard removal
724666ea1b28a76aeba74744148b15099254d918671Owen Lin                // properly it could happen
725666ea1b28a76aeba74744148b15099254d918671Owen Lin                if (image == null) {
726666ea1b28a76aeba74744148b15099254d918671Owen Lin                    return;
727666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
728666ea1b28a76aeba74744148b15099254d918671Owen Lin
729666ea1b28a76aeba74744148b15099254d918671Owen Lin                ArrayList<MenuItem> enableList = new ArrayList<MenuItem>();
730666ea1b28a76aeba74744148b15099254d918671Owen Lin                ArrayList<MenuItem> disableList = new ArrayList<MenuItem>();
731666ea1b28a76aeba74744148b15099254d918671Owen Lin                ArrayList<MenuItem> list;
732666ea1b28a76aeba74744148b15099254d918671Owen Lin
733666ea1b28a76aeba74744148b15099254d918671Owen Lin                list = image.isReadonly() ? disableList : enableList;
734666ea1b28a76aeba74744148b15099254d918671Owen Lin                list.addAll(requiresWriteAccessItems);
735666ea1b28a76aeba74744148b15099254d918671Owen Lin
736666ea1b28a76aeba74744148b15099254d918671Owen Lin                list = image.isDrm() ? disableList : enableList;
737666ea1b28a76aeba74744148b15099254d918671Owen Lin                list.addAll(requiresNoDrmAccessItems);
738666ea1b28a76aeba74744148b15099254d918671Owen Lin
739666ea1b28a76aeba74744148b15099254d918671Owen Lin                list = ImageManager.isImage(image) ? enableList : disableList;
740666ea1b28a76aeba74744148b15099254d918671Owen Lin                list.addAll(requiresImageItems);
741666ea1b28a76aeba74744148b15099254d918671Owen Lin
742666ea1b28a76aeba74744148b15099254d918671Owen Lin                list = ImageManager.isVideo(image) ? enableList : disableList;
743666ea1b28a76aeba74744148b15099254d918671Owen Lin                list.addAll(requiresVideoItems);
744666ea1b28a76aeba74744148b15099254d918671Owen Lin
745666ea1b28a76aeba74744148b15099254d918671Owen Lin                for (MenuItem item : enableList) {
746666ea1b28a76aeba74744148b15099254d918671Owen Lin                    item.setVisible(true);
747666ea1b28a76aeba74744148b15099254d918671Owen Lin                    item.setEnabled(true);
748666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
749666ea1b28a76aeba74744148b15099254d918671Owen Lin
750666ea1b28a76aeba74744148b15099254d918671Owen Lin                for (MenuItem item : disableList) {
751666ea1b28a76aeba74744148b15099254d918671Owen Lin                    item.setVisible(false);
752666ea1b28a76aeba74744148b15099254d918671Owen Lin                    item.setEnabled(false);
753666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
754666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
755666ea1b28a76aeba74744148b15099254d918671Owen Lin
756666ea1b28a76aeba74744148b15099254d918671Owen Lin            // must override abstract method
757666ea1b28a76aeba74744148b15099254d918671Owen Lin            public void aboutToCall(MenuItem menu, IImage image) {
758666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
759666ea1b28a76aeba74744148b15099254d918671Owen Lin        };
760666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
761666ea1b28a76aeba74744148b15099254d918671Owen Lin
762666ea1b28a76aeba74744148b15099254d918671Owen Lin    static void deletePhoto(Activity activity, Runnable onDelete) {
763666ea1b28a76aeba74744148b15099254d918671Owen Lin        deleteImpl(activity, onDelete, true);
764666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
765666ea1b28a76aeba74744148b15099254d918671Owen Lin
766666ea1b28a76aeba74744148b15099254d918671Owen Lin    static void deleteImage(
767666ea1b28a76aeba74744148b15099254d918671Owen Lin            Activity activity, Runnable onDelete, IImage image) {
768666ea1b28a76aeba74744148b15099254d918671Owen Lin        deleteImpl(activity, onDelete, ImageManager.isImage(image));
769666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
770666ea1b28a76aeba74744148b15099254d918671Owen Lin
771666ea1b28a76aeba74744148b15099254d918671Owen Lin    static void deleteImpl(
772666ea1b28a76aeba74744148b15099254d918671Owen Lin            Activity activity, Runnable onDelete, boolean isImage) {
773666ea1b28a76aeba74744148b15099254d918671Owen Lin        boolean needConfirm = PreferenceManager
774666ea1b28a76aeba74744148b15099254d918671Owen Lin                 .getDefaultSharedPreferences(activity)
775666ea1b28a76aeba74744148b15099254d918671Owen Lin                 .getBoolean("pref_gallery_confirm_delete_key", true);
776666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (!needConfirm) {
777666ea1b28a76aeba74744148b15099254d918671Owen Lin            if (onDelete != null) onDelete.run();
778666ea1b28a76aeba74744148b15099254d918671Owen Lin        } else {
779666ea1b28a76aeba74744148b15099254d918671Owen Lin            String title = activity.getString(R.string.confirm_delete_title);
780666ea1b28a76aeba74744148b15099254d918671Owen Lin            String message = activity.getString(isImage
781666ea1b28a76aeba74744148b15099254d918671Owen Lin                    ? R.string.confirm_delete_message
782666ea1b28a76aeba74744148b15099254d918671Owen Lin                    : R.string.confirm_delete_video_message);
783666ea1b28a76aeba74744148b15099254d918671Owen Lin            confirmAction(activity, title, message, onDelete);
784666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
785666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
786666ea1b28a76aeba74744148b15099254d918671Owen Lin
787666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static void deleteMultiple(Context context, Runnable action) {
788666ea1b28a76aeba74744148b15099254d918671Owen Lin        boolean needConfirm = PreferenceManager
789666ea1b28a76aeba74744148b15099254d918671Owen Lin            .getDefaultSharedPreferences(context)
790666ea1b28a76aeba74744148b15099254d918671Owen Lin            .getBoolean("pref_gallery_confirm_delete_key", true);
791666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (!needConfirm) {
792666ea1b28a76aeba74744148b15099254d918671Owen Lin            if (action != null) action.run();
793666ea1b28a76aeba74744148b15099254d918671Owen Lin        } else {
794666ea1b28a76aeba74744148b15099254d918671Owen Lin            String title = context.getString(R.string.confirm_delete_title);
795666ea1b28a76aeba74744148b15099254d918671Owen Lin            String message = context.getString(
796666ea1b28a76aeba74744148b15099254d918671Owen Lin                    R.string.confirm_delete_multiple_message);
797666ea1b28a76aeba74744148b15099254d918671Owen Lin            confirmAction(context, title, message, action);
798666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
799666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
800666ea1b28a76aeba74744148b15099254d918671Owen Lin
801666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static void confirmAction(Context context, String title,
802666ea1b28a76aeba74744148b15099254d918671Owen Lin            String message, final Runnable action) {
803666ea1b28a76aeba74744148b15099254d918671Owen Lin        OnClickListener listener = new OnClickListener() {
804666ea1b28a76aeba74744148b15099254d918671Owen Lin            public void onClick(DialogInterface dialog, int which) {
805666ea1b28a76aeba74744148b15099254d918671Owen Lin                switch (which) {
806666ea1b28a76aeba74744148b15099254d918671Owen Lin                    case DialogInterface.BUTTON_POSITIVE:
807666ea1b28a76aeba74744148b15099254d918671Owen Lin                        if (action != null) action.run();
808666ea1b28a76aeba74744148b15099254d918671Owen Lin                }
809666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
810666ea1b28a76aeba74744148b15099254d918671Owen Lin        };
811666ea1b28a76aeba74744148b15099254d918671Owen Lin        new AlertDialog.Builder(context)
812666ea1b28a76aeba74744148b15099254d918671Owen Lin            .setIcon(android.R.drawable.ic_dialog_alert)
813666ea1b28a76aeba74744148b15099254d918671Owen Lin            .setTitle(title)
814666ea1b28a76aeba74744148b15099254d918671Owen Lin            .setMessage(message)
815666ea1b28a76aeba74744148b15099254d918671Owen Lin            .setPositiveButton(android.R.string.ok, listener)
816666ea1b28a76aeba74744148b15099254d918671Owen Lin            .setNegativeButton(android.R.string.cancel, listener)
817666ea1b28a76aeba74744148b15099254d918671Owen Lin            .create()
818666ea1b28a76aeba74744148b15099254d918671Owen Lin            .show();
819666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
820666ea1b28a76aeba74744148b15099254d918671Owen Lin
821666ea1b28a76aeba74744148b15099254d918671Owen Lin    static void addCapturePictureMenuItems(Menu menu, final Activity activity) {
822666ea1b28a76aeba74744148b15099254d918671Owen Lin        menu.add(Menu.NONE, Menu.NONE, POSITION_CAPTURE_PICTURE,
823666ea1b28a76aeba74744148b15099254d918671Owen Lin                R.string.capture_picture)
824666ea1b28a76aeba74744148b15099254d918671Owen Lin                .setOnMenuItemClickListener(
825666ea1b28a76aeba74744148b15099254d918671Owen Lin                new MenuItem.OnMenuItemClickListener() {
826666ea1b28a76aeba74744148b15099254d918671Owen Lin                    public boolean onMenuItemClick(MenuItem item) {
827666ea1b28a76aeba74744148b15099254d918671Owen Lin                        return onCapturePictureClicked(activity);
828666ea1b28a76aeba74744148b15099254d918671Owen Lin                    }
829666ea1b28a76aeba74744148b15099254d918671Owen Lin                }).setIcon(android.R.drawable.ic_menu_camera);
830666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
831666ea1b28a76aeba74744148b15099254d918671Owen Lin
832666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static boolean onCapturePictureClicked(Activity activity) {
833666ea1b28a76aeba74744148b15099254d918671Owen Lin        Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
834666ea1b28a76aeba74744148b15099254d918671Owen Lin        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
835666ea1b28a76aeba74744148b15099254d918671Owen Lin        try {
836666ea1b28a76aeba74744148b15099254d918671Owen Lin            activity.startActivity(intent);
837666ea1b28a76aeba74744148b15099254d918671Owen Lin        } catch (android.content.ActivityNotFoundException e) {
838666ea1b28a76aeba74744148b15099254d918671Owen Lin            // Ignore exception
839666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
840666ea1b28a76aeba74744148b15099254d918671Owen Lin        return true;
841666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
842666ea1b28a76aeba74744148b15099254d918671Owen Lin
843666ea1b28a76aeba74744148b15099254d918671Owen Lin    static void addCaptureVideoMenuItems(Menu menu, final Activity activity) {
844666ea1b28a76aeba74744148b15099254d918671Owen Lin        menu.add(Menu.NONE, Menu.NONE, POSITION_CAPTURE_VIDEO,
845666ea1b28a76aeba74744148b15099254d918671Owen Lin                R.string.capture_video)
846666ea1b28a76aeba74744148b15099254d918671Owen Lin                .setOnMenuItemClickListener(
847666ea1b28a76aeba74744148b15099254d918671Owen Lin                new MenuItem.OnMenuItemClickListener() {
848666ea1b28a76aeba74744148b15099254d918671Owen Lin                    public boolean onMenuItemClick(MenuItem item) {
849666ea1b28a76aeba74744148b15099254d918671Owen Lin                        return onCaptureVideoClicked(activity);
850666ea1b28a76aeba74744148b15099254d918671Owen Lin                    }
851666ea1b28a76aeba74744148b15099254d918671Owen Lin                }).setIcon(R.drawable.ic_menu_camera_video_view);
852666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
853666ea1b28a76aeba74744148b15099254d918671Owen Lin
854666ea1b28a76aeba74744148b15099254d918671Owen Lin    private static boolean onCaptureVideoClicked(Activity activity) {
855666ea1b28a76aeba74744148b15099254d918671Owen Lin        Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
856666ea1b28a76aeba74744148b15099254d918671Owen Lin        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
857666ea1b28a76aeba74744148b15099254d918671Owen Lin        try {
858666ea1b28a76aeba74744148b15099254d918671Owen Lin            activity.startActivity(intent);
859666ea1b28a76aeba74744148b15099254d918671Owen Lin        } catch (android.content.ActivityNotFoundException e) {
860666ea1b28a76aeba74744148b15099254d918671Owen Lin            // Ignore exception
861666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
862666ea1b28a76aeba74744148b15099254d918671Owen Lin        return true;
863666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
864666ea1b28a76aeba74744148b15099254d918671Owen Lin
865666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static void addCaptureMenuItems(Menu menu, final Activity activity) {
866666ea1b28a76aeba74744148b15099254d918671Owen Lin        addCapturePictureMenuItems(menu, activity);
867666ea1b28a76aeba74744148b15099254d918671Owen Lin        addCaptureVideoMenuItems(menu, activity);
868666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
869666ea1b28a76aeba74744148b15099254d918671Owen Lin
870666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static String formatDuration(final Context context,
871666ea1b28a76aeba74744148b15099254d918671Owen Lin            int durationMs) {
872666ea1b28a76aeba74744148b15099254d918671Owen Lin        int duration = durationMs / 1000;
873666ea1b28a76aeba74744148b15099254d918671Owen Lin        int h = duration / 3600;
874666ea1b28a76aeba74744148b15099254d918671Owen Lin        int m = (duration - h * 3600) / 60;
875666ea1b28a76aeba74744148b15099254d918671Owen Lin        int s = duration - (h * 3600 + m * 60);
876666ea1b28a76aeba74744148b15099254d918671Owen Lin        String durationValue;
877666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (h == 0) {
878666ea1b28a76aeba74744148b15099254d918671Owen Lin            durationValue = String.format(
879666ea1b28a76aeba74744148b15099254d918671Owen Lin                    context.getString(R.string.details_ms), m, s);
880666ea1b28a76aeba74744148b15099254d918671Owen Lin        } else {
881666ea1b28a76aeba74744148b15099254d918671Owen Lin            durationValue = String.format(
882666ea1b28a76aeba74744148b15099254d918671Owen Lin                    context.getString(R.string.details_hms), h, m, s);
883666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
884666ea1b28a76aeba74744148b15099254d918671Owen Lin        return durationValue;
885666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
886666ea1b28a76aeba74744148b15099254d918671Owen Lin
887666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static void showStorageToast(Activity activity) {
888666ea1b28a76aeba74744148b15099254d918671Owen Lin        showStorageToast(activity, calculatePicturesRemaining());
889666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
890666ea1b28a76aeba74744148b15099254d918671Owen Lin
891666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static void showStorageToast(Activity activity, int remaining) {
892666ea1b28a76aeba74744148b15099254d918671Owen Lin        String noStorageText = null;
893666ea1b28a76aeba74744148b15099254d918671Owen Lin
894666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (remaining == MenuHelper.NO_STORAGE_ERROR) {
895666ea1b28a76aeba74744148b15099254d918671Owen Lin            String state = Environment.getExternalStorageState();
896666ea1b28a76aeba74744148b15099254d918671Owen Lin            if (state == Environment.MEDIA_CHECKING) {
897666ea1b28a76aeba74744148b15099254d918671Owen Lin                noStorageText = activity.getString(R.string.preparing_sd);
898666ea1b28a76aeba74744148b15099254d918671Owen Lin            } else {
899666ea1b28a76aeba74744148b15099254d918671Owen Lin                noStorageText = activity.getString(R.string.no_storage);
900666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
901666ea1b28a76aeba74744148b15099254d918671Owen Lin        } else if (remaining < 1) {
902666ea1b28a76aeba74744148b15099254d918671Owen Lin            noStorageText = activity.getString(R.string.not_enough_space);
903666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
904666ea1b28a76aeba74744148b15099254d918671Owen Lin
905666ea1b28a76aeba74744148b15099254d918671Owen Lin        if (noStorageText != null) {
906666ea1b28a76aeba74744148b15099254d918671Owen Lin            Toast.makeText(activity, noStorageText, 5000).show();
907666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
908666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
909666ea1b28a76aeba74744148b15099254d918671Owen Lin
910666ea1b28a76aeba74744148b15099254d918671Owen Lin    public static int calculatePicturesRemaining() {
911666ea1b28a76aeba74744148b15099254d918671Owen Lin        try {
912666ea1b28a76aeba74744148b15099254d918671Owen Lin            if (!ImageManager.hasStorage()) {
913666ea1b28a76aeba74744148b15099254d918671Owen Lin                return NO_STORAGE_ERROR;
914666ea1b28a76aeba74744148b15099254d918671Owen Lin            } else {
915666ea1b28a76aeba74744148b15099254d918671Owen Lin                String storageDirectory =
916666ea1b28a76aeba74744148b15099254d918671Owen Lin                        Environment.getExternalStorageDirectory().toString();
917666ea1b28a76aeba74744148b15099254d918671Owen Lin                StatFs stat = new StatFs(storageDirectory);
918666ea1b28a76aeba74744148b15099254d918671Owen Lin                float remaining = ((float) stat.getAvailableBlocks()
919666ea1b28a76aeba74744148b15099254d918671Owen Lin                        * (float) stat.getBlockSize()) / 400000F;
920666ea1b28a76aeba74744148b15099254d918671Owen Lin                return (int) remaining;
921666ea1b28a76aeba74744148b15099254d918671Owen Lin            }
922666ea1b28a76aeba74744148b15099254d918671Owen Lin        } catch (Exception ex) {
923666ea1b28a76aeba74744148b15099254d918671Owen Lin            // if we can't stat the filesystem then we don't know how many
924666ea1b28a76aeba74744148b15099254d918671Owen Lin            // pictures are remaining.  it might be zero but just leave it
925666ea1b28a76aeba74744148b15099254d918671Owen Lin            // blank since we really don't know.
926666ea1b28a76aeba74744148b15099254d918671Owen Lin            return CANNOT_STAT_ERROR;
927666ea1b28a76aeba74744148b15099254d918671Owen Lin        }
928666ea1b28a76aeba74744148b15099254d918671Owen Lin    }
929666ea1b28a76aeba74744148b15099254d918671Owen Lin}
930