1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.gallery3d.app;
18
19import android.app.Dialog;
20import android.content.AsyncQueryHandler;
21import android.content.ContentResolver;
22import android.content.DialogInterface;
23import android.content.DialogInterface.OnCancelListener;
24import android.content.Intent;
25import android.database.Cursor;
26import android.net.Uri;
27import android.os.Bundle;
28import android.provider.OpenableColumns;
29import android.view.Menu;
30import android.view.Window;
31import android.widget.Toast;
32
33import com.android.gallery3d.R;
34import com.android.gallery3d.common.Utils;
35import com.android.gallery3d.data.DataManager;
36import com.android.gallery3d.data.MediaItem;
37import com.android.gallery3d.data.MediaSet;
38import com.android.gallery3d.data.Path;
39import com.android.gallery3d.picasasource.PicasaSource;
40import com.android.gallery3d.ui.GLRoot;
41import com.android.gallery3d.util.GalleryUtils;
42
43public final class Gallery extends AbstractGalleryActivity implements OnCancelListener {
44    public static final String EXTRA_SLIDESHOW = "slideshow";
45    public static final String EXTRA_DREAM = "dream";
46    public static final String EXTRA_CROP = "crop";
47
48    public static final String ACTION_REVIEW = "com.android.camera.action.REVIEW";
49    public static final String KEY_GET_CONTENT = "get-content";
50    public static final String KEY_GET_ALBUM = "get-album";
51    public static final String KEY_TYPE_BITS = "type-bits";
52    public static final String KEY_MEDIA_TYPES = "mediaTypes";
53
54    private static final String TAG = "Gallery";
55    private Dialog mVersionCheckDialog;
56
57    @Override
58    protected void onCreate(Bundle savedInstanceState) {
59        super.onCreate(savedInstanceState);
60        requestWindowFeature(Window.FEATURE_ACTION_BAR);
61        requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
62
63        setContentView(R.layout.main);
64
65        if (savedInstanceState != null) {
66            getStateManager().restoreFromState(savedInstanceState);
67        } else {
68            initializeByIntent();
69        }
70    }
71
72    private void initializeByIntent() {
73        Intent intent = getIntent();
74        String action = intent.getAction();
75
76        if (Intent.ACTION_GET_CONTENT.equalsIgnoreCase(action)) {
77            startGetContent(intent);
78        } else if (Intent.ACTION_PICK.equalsIgnoreCase(action)) {
79            // We do NOT really support the PICK intent. Handle it as
80            // the GET_CONTENT. However, we need to translate the type
81            // in the intent here.
82            Log.w(TAG, "action PICK is not supported");
83            String type = Utils.ensureNotNull(intent.getType());
84            if (type.startsWith("vnd.android.cursor.dir/")) {
85                if (type.endsWith("/image")) intent.setType("image/*");
86                if (type.endsWith("/video")) intent.setType("video/*");
87            }
88            startGetContent(intent);
89        } else if (Intent.ACTION_VIEW.equalsIgnoreCase(action)
90                || ACTION_REVIEW.equalsIgnoreCase(action)){
91            startViewAction(intent);
92        } else {
93            startDefaultPage();
94        }
95    }
96
97    public void startDefaultPage() {
98        PicasaSource.showSignInReminder(this);
99        Bundle data = new Bundle();
100        data.putString(AlbumSetPage.KEY_MEDIA_PATH,
101                getDataManager().getTopSetPath(DataManager.INCLUDE_ALL));
102        getStateManager().startState(AlbumSetPage.class, data);
103        mVersionCheckDialog = PicasaSource.getVersionCheckDialog(this);
104        if (mVersionCheckDialog != null) {
105            mVersionCheckDialog.setOnCancelListener(this);
106        }
107    }
108
109    private void startGetContent(Intent intent) {
110        Bundle data = intent.getExtras() != null
111                ? new Bundle(intent.getExtras())
112                : new Bundle();
113        data.putBoolean(KEY_GET_CONTENT, true);
114        int typeBits = GalleryUtils.determineTypeBits(this, intent);
115        data.putInt(KEY_TYPE_BITS, typeBits);
116        data.putString(AlbumSetPage.KEY_MEDIA_PATH,
117                getDataManager().getTopSetPath(typeBits));
118        getStateManager().startState(AlbumSetPage.class, data);
119    }
120
121    private String getContentType(Intent intent) {
122        String type = intent.getType();
123        if (type != null) return type;
124
125        Uri uri = intent.getData();
126        try {
127            return getContentResolver().getType(uri);
128        } catch (Throwable t) {
129            Log.w(TAG, "get type fail", t);
130            return null;
131        }
132    }
133
134    private void startViewAction(Intent intent) {
135        Boolean slideshow = intent.getBooleanExtra(EXTRA_SLIDESHOW, false);
136        if (slideshow) {
137            getActionBar().hide();
138            DataManager manager = getDataManager();
139            Path path = manager.findPathByUri(intent.getData(), intent.getType());
140            if (path == null || manager.getMediaObject(path)
141                    instanceof MediaItem) {
142                path = Path.fromString(
143                        manager.getTopSetPath(DataManager.INCLUDE_IMAGE));
144            }
145            Bundle data = new Bundle();
146            data.putString(SlideshowPage.KEY_SET_PATH, path.toString());
147            data.putBoolean(SlideshowPage.KEY_RANDOM_ORDER, true);
148            data.putBoolean(SlideshowPage.KEY_REPEAT, true);
149            if (intent.getBooleanExtra(EXTRA_DREAM, false)) {
150                data.putBoolean(SlideshowPage.KEY_DREAM, true);
151            }
152            getStateManager().startState(SlideshowPage.class, data);
153        } else {
154            Bundle data = new Bundle();
155            DataManager dm = getDataManager();
156            Uri uri = intent.getData();
157            String contentType = getContentType(intent);
158            if (contentType == null) {
159                Toast.makeText(this,
160                        R.string.no_such_item, Toast.LENGTH_LONG).show();
161                finish();
162                return;
163            }
164            if (uri == null) {
165                int typeBits = GalleryUtils.determineTypeBits(this, intent);
166                data.putInt(KEY_TYPE_BITS, typeBits);
167                data.putString(AlbumSetPage.KEY_MEDIA_PATH,
168                        getDataManager().getTopSetPath(typeBits));
169                getStateManager().startState(AlbumSetPage.class, data);
170            } else if (contentType.startsWith(
171                    ContentResolver.CURSOR_DIR_BASE_TYPE)) {
172                int mediaType = intent.getIntExtra(KEY_MEDIA_TYPES, 0);
173                if (mediaType != 0) {
174                    uri = uri.buildUpon().appendQueryParameter(
175                            KEY_MEDIA_TYPES, String.valueOf(mediaType))
176                            .build();
177                }
178                Path setPath = dm.findPathByUri(uri, null);
179                MediaSet mediaSet = null;
180                if (setPath != null) {
181                    mediaSet = (MediaSet) dm.getMediaObject(setPath);
182                }
183                if (mediaSet != null) {
184                    if (mediaSet.isLeafAlbum()) {
185                        data.putString(AlbumPage.KEY_MEDIA_PATH, setPath.toString());
186                        data.putString(AlbumPage.KEY_PARENT_MEDIA_PATH,
187                                dm.getTopSetPath(DataManager.INCLUDE_ALL));
188                        getStateManager().startState(AlbumPage.class, data);
189                    } else {
190                        data.putString(AlbumSetPage.KEY_MEDIA_PATH, setPath.toString());
191                        getStateManager().startState(AlbumSetPage.class, data);
192                    }
193                } else {
194                    startDefaultPage();
195                }
196            } else {
197                Path itemPath = dm.findPathByUri(uri, intent.getType());
198                Path albumPath = dm.getDefaultSetOf(itemPath);
199                // TODO: Make this parameter public so other activities can reference it.
200                boolean singleItemOnly = intent.getBooleanExtra("SingleItemOnly", false);
201                if (!singleItemOnly && (albumPath != null)) {
202                    data.putString(PhotoPage.KEY_MEDIA_SET_PATH, albumPath.toString());
203                }
204                data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, itemPath.toString());
205                if (intent.getBooleanExtra(PhotoPage.KEY_TREAT_BACK_AS_UP, false)) {
206                    data.putBoolean(PhotoPage.KEY_TREAT_BACK_AS_UP, true);
207                }
208
209                // Displays the filename as title, reading the filename from the interface:
210                // {@link android.provider.OpenableColumns#DISPLAY_NAME}.
211                AsyncQueryHandler queryHandler = new AsyncQueryHandler(getContentResolver()) {
212                    @Override
213                    protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
214                        try {
215                            if ((cursor != null) && cursor.moveToFirst()) {
216                                String displayName = cursor.getString(0);
217
218                                // Just show empty title if other apps don't set DISPLAY_NAME
219                                setTitle((displayName == null) ? "" : displayName);
220                            }
221                        } finally {
222                            Utils.closeSilently(cursor);
223                        }
224                    }
225                };
226                queryHandler.startQuery(0, null, uri, new String[] {OpenableColumns.DISPLAY_NAME},
227                        null, null, null);
228
229                getStateManager().startState(PhotoPage.class, data);
230            }
231        }
232    }
233
234    @Override
235    public boolean onCreateOptionsMenu(Menu menu) {
236        super.onCreateOptionsMenu(menu);
237        return getStateManager().createOptionsMenu(menu);
238    }
239
240    @Override
241    protected void onResume() {
242        Utils.assertTrue(getStateManager().getStateCount() > 0);
243        super.onResume();
244        if (mVersionCheckDialog != null) {
245            mVersionCheckDialog.show();
246        }
247    }
248
249    @Override
250    protected void onPause() {
251        super.onPause();
252        if (mVersionCheckDialog != null) {
253            mVersionCheckDialog.dismiss();
254        }
255    }
256
257    @Override
258    public void onCancel(DialogInterface dialog) {
259        if (dialog == mVersionCheckDialog) {
260            mVersionCheckDialog = null;
261        }
262    }
263}
264