1/*
2 * Copyright (C) 2015 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.messaging.ui.photoviewer;
18
19import android.Manifest;
20import android.app.Activity;
21import android.content.Context;
22import android.content.Intent;
23import android.database.Cursor;
24import android.net.Uri;
25import android.os.Bundle;
26import android.support.v4.app.FragmentManager;
27import android.support.v4.content.Loader;
28import android.text.TextUtils;
29import android.view.Menu;
30import android.view.MenuItem;
31import android.widget.ShareActionProvider;
32import android.widget.Toast;
33
34import com.android.ex.photo.PhotoViewController;
35import com.android.ex.photo.adapters.PhotoPagerAdapter;
36import com.android.ex.photo.loaders.PhotoBitmapLoaderInterface.BitmapResult;
37import com.android.messaging.R;
38import com.android.messaging.datamodel.ConversationImagePartsView.PhotoViewQuery;
39import com.android.messaging.datamodel.MediaScratchFileProvider;
40import com.android.messaging.ui.conversation.ConversationFragment;
41import com.android.messaging.util.Dates;
42import com.android.messaging.util.LogUtil;
43import com.android.messaging.util.OsUtil;
44
45/**
46 * Customizations for the photoviewer to display conversation images in full screen.
47 */
48public class BuglePhotoViewController extends PhotoViewController {
49    private ShareActionProvider mShareActionProvider;
50    private MenuItem mShareItem;
51    private MenuItem mSaveItem;
52
53    public BuglePhotoViewController(final ActivityInterface activity) {
54        super(activity);
55    }
56
57    @Override
58    public Loader<BitmapResult> onCreateBitmapLoader(
59            final int id, final Bundle args, final String uri) {
60        switch (id) {
61            case BITMAP_LOADER_AVATAR:
62            case BITMAP_LOADER_THUMBNAIL:
63            case BITMAP_LOADER_PHOTO:
64                return new BuglePhotoBitmapLoader(getActivity().getContext(), uri);
65            default:
66                LogUtil.e(LogUtil.BUGLE_TAG,
67                        "Photoviewer unable to open bitmap loader with unknown id: " + id);
68                return null;
69        }
70    }
71
72    @Override
73    public void updateActionBar() {
74        final Cursor cursor = getCursorAtProperPosition();
75
76        if (mSaveItem == null || cursor == null) {
77            // Load not finished, called from framework code before ready
78            return;
79        }
80        // Show the name as the title
81        mActionBarTitle = cursor.getString(PhotoViewQuery.INDEX_SENDER_FULL_NAME);
82        if (TextUtils.isEmpty(mActionBarTitle)) {
83            // If the name is not known, fall back to the phone number
84            mActionBarTitle = cursor.getString(PhotoViewQuery.INDEX_DISPLAY_DESTINATION);
85        }
86
87        // Show the timestamp as the subtitle
88        final long receivedTimestamp = cursor.getLong(PhotoViewQuery.INDEX_RECEIVED_TIMESTAMP);
89        mActionBarSubtitle = Dates.getMessageTimeString(receivedTimestamp).toString();
90
91        setActionBarTitles(getActivity().getActionBarInterface());
92        mSaveItem.setVisible(!isTempFile());
93
94        updateShareActionProvider();
95    }
96
97    private void updateShareActionProvider() {
98        final PhotoPagerAdapter adapter = getAdapter();
99        final Cursor cursor = getCursorAtProperPosition();
100        if (mShareActionProvider == null || mShareItem == null || adapter == null ||
101                cursor == null) {
102            // Not enough stuff loaded to update the share action
103            return;
104        }
105        final String photoUri = adapter.getPhotoUri(cursor);
106        if (isTempFile()) {
107            mShareItem.setVisible(false);
108            return;
109        }
110        final String contentType = adapter.getContentType(cursor);
111
112        final Intent shareIntent = new Intent();
113        shareIntent.setAction(Intent.ACTION_SEND);
114        shareIntent.setType(contentType);
115        shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(photoUri));
116        mShareActionProvider.setShareIntent(shareIntent);
117        mShareItem.setVisible(true);
118    }
119
120    /**
121     * Checks whether the current photo is a temp file.  A temp file can be deleted at any time, so
122     * we need to disable share and save options because the file may no longer be there.
123     */
124    private boolean isTempFile() {
125        final Cursor cursor = getCursorAtProperPosition();
126        final Uri photoUri = Uri.parse(getAdapter().getPhotoUri(cursor));
127        return MediaScratchFileProvider.isMediaScratchSpaceUri(photoUri);
128    }
129
130    @Override
131    public boolean onCreateOptionsMenu(final Menu menu) {
132        ((Activity) getActivity()).getMenuInflater().inflate(R.menu.photo_view_menu, menu);
133
134        // Get the ShareActionProvider
135        mShareItem = menu.findItem(R.id.action_share);
136        mShareActionProvider = (ShareActionProvider) mShareItem.getActionProvider();
137        updateShareActionProvider();
138
139        mSaveItem = menu.findItem(R.id.action_save);
140        return true;
141    }
142
143    @Override
144    public boolean onPrepareOptionsMenu(final Menu menu) {
145        return !mIsEmpty;
146    }
147
148    @Override
149    public boolean onOptionsItemSelected(final MenuItem item) {
150        if (item.getItemId() == R.id.action_save) {
151            if (OsUtil.hasStoragePermission()) {
152                final PhotoPagerAdapter adapter = getAdapter();
153                final Cursor cursor = getCursorAtProperPosition();
154                if (cursor == null) {
155                    final Context context = getActivity().getContext();
156                    final String error = context.getResources().getQuantityString(
157                            R.plurals.attachment_save_error, 1, 1);
158                    Toast.makeText(context, error, Toast.LENGTH_SHORT).show();
159                    return true;
160                }
161                final String photoUri = adapter.getPhotoUri(cursor);
162                new ConversationFragment.SaveAttachmentTask(((Activity) getActivity()),
163                        Uri.parse(photoUri), adapter.getContentType(cursor)).executeOnThreadPool();
164            } else {
165                ((Activity)getActivity()).requestPermissions(
166                        new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
167            }
168            return true;
169        } else {
170            return super.onOptionsItemSelected(item);
171        }
172    }
173
174    @Override
175    public PhotoPagerAdapter createPhotoPagerAdapter(final Context context,
176            final FragmentManager fm, final Cursor c, final float maxScale) {
177        return new BuglePhotoPageAdapter(context, fm, c, maxScale, mDisplayThumbsFullScreen);
178    }
179}
180