1 /*
2  * Copyright (C) 2010 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 
17 package com.android.camera.ui;
18 
19 import com.android.camera.R;
20 import com.android.camera.Util;
21 
22 import android.app.Activity;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.pm.ActivityInfo;
27 import android.content.pm.PackageManager;
28 import android.content.pm.ResolveInfo;
29 import android.content.res.Resources;
30 import android.graphics.Bitmap;
31 import android.graphics.drawable.ColorDrawable;
32 import android.graphics.drawable.Drawable;
33 import android.net.Uri;
34 import android.view.LayoutInflater;
35 import android.view.MotionEvent;
36 import android.view.View;
37 import android.view.ViewGroup;
38 import android.view.ViewGroup.LayoutParams;
39 import android.view.WindowManager;
40 import android.widget.AdapterView;
41 import android.widget.GridView;
42 import android.widget.ImageView;
43 import android.widget.PopupWindow;
44 import android.widget.SimpleAdapter;
45 
46 import java.util.ArrayList;
47 import java.util.HashMap;
48 import java.util.List;
49 import java.util.Map;
50 
51 // A popup window that contains a big thumbnail and a list of apps to share.
52 public class SharePopup extends PopupWindow implements View.OnClickListener,
53         View.OnTouchListener, AdapterView.OnItemClickListener, Rotatable {
54     private static final String TAG = "SharePopup";
55     private static final String ADAPTER_COLUMN_ICON = "icon";
56     private Context mContext;
57     private Uri mUri;
58     private String mMimeType;
59     private ImageView mThumbnail;
60     private int mBitmapWidth;
61     private int mBitmapHeight;
62     private int mOrientation;
63     private int mActivityOrientation;
64     // A view that contains a list of application icons and the share view.
65     private View mRootView;
66     // The list of the application icons.
67     private GridView mShareList;
68     // A rotated view that contains the thumbnail and the play icon.
69     private RotateLayout mThumbnailRotateLayout;
70     private RotateLayout mGotoGalleryRotate;
71     private View mPreviewFrame;
72     private ArrayList<ComponentName> mComponent = new ArrayList<ComponentName>();
73     private View mImageViewFrame;
74 
75     private class MySimpleAdapter extends SimpleAdapter {
MySimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)76         public MySimpleAdapter(Context context, List<? extends Map<String, ?>> data,
77                 int resource, String[] from, int[] to) {
78             super(context, data, resource, from, to);
79         }
80 
81         @Override
getView(int position, View convertView, ViewGroup parent)82         public View getView(int position, View convertView, ViewGroup parent) {
83             View v = super.getView(position, convertView, parent);
84             RotateLayout r = (RotateLayout) v.findViewById(R.id.share_icon_rotate_layout);
85             r.setOrientation(mOrientation);
86             return v;
87         }
88     }
89 
90     private final SimpleAdapter.ViewBinder mViewBinder =
91         new SimpleAdapter.ViewBinder() {
92             @Override
93             public boolean setViewValue(final View view, final Object data,
94                     final String text) {
95                 if (view instanceof ImageView) {
96                     ((ImageView) view).setImageDrawable((Drawable) data);
97                     return true;
98                 }
99                 return false;
100             }
101         };
102 
SharePopup(Activity activity, Uri uri, Bitmap bitmap, int orientation, View previewFrame)103     public SharePopup(Activity activity, Uri uri, Bitmap bitmap, int orientation,
104             View previewFrame) {
105         super(activity);
106 
107         mActivityOrientation = activity.getRequestedOrientation();
108 
109         // Initialize variables
110         mContext = activity;
111         mUri = uri;
112         mMimeType = mContext.getContentResolver().getType(mUri);
113         mPreviewFrame = previewFrame;
114         LayoutInflater inflater = activity.getLayoutInflater();
115         ViewGroup sharePopup = (ViewGroup) inflater.inflate(R.layout.share_popup, null, false);
116         // This is required because popup window is full screen.
117         sharePopup.setOnTouchListener(this);
118         mThumbnailRotateLayout =
119                 (RotateLayout) sharePopup.findViewById(R.id.thumbnail_rotate_layout);
120         mShareList = (GridView) sharePopup.findViewById(R.id.share_list);
121         mThumbnail = (ImageView) sharePopup.findViewById(R.id.thumbnail);
122         mThumbnail.setImageBitmap(bitmap);
123         mImageViewFrame =
124                 (View) sharePopup.findViewById(R.id.thumbnail_image_frame);
125         mImageViewFrame.setOnClickListener(this);
126 
127 
128         mGotoGalleryRotate =
129                 (RotateLayout) sharePopup.findViewById(R.id.goto_gallery_button_rotate);
130         sharePopup.findViewById(R.id.goto_gallery_button).setOnClickListener(this);
131 
132         mBitmapWidth = bitmap.getWidth();
133         mBitmapHeight = bitmap.getHeight();
134 
135         // Show play button if this is a video thumbnail.
136         if (mMimeType.startsWith("video/")) {
137             sharePopup.findViewById(R.id.play).setVisibility(View.VISIBLE);
138         }
139         mBitmapWidth = bitmap.getWidth();
140         mBitmapHeight = bitmap.getHeight();
141 
142         Resources res = mContext.getResources();
143 
144         // Initialize popup window size.
145         mRootView = sharePopup.findViewById(R.id.root);
146         LayoutParams params = mRootView.getLayoutParams();
147         params.width = previewFrame.getWidth();
148         params.height = previewFrame.getHeight();
149         mRootView.setLayoutParams(params);
150 
151         // Initialize popup window.
152         setWidth(WindowManager.LayoutParams.MATCH_PARENT);
153         setHeight(WindowManager.LayoutParams.MATCH_PARENT);
154         setBackgroundDrawable(new ColorDrawable());
155         setContentView(sharePopup);
156         setOrientation(orientation);
157         setFocusable(true);
158         setAnimationStyle(R.style.AnimationPopup);
159         createShareMenu();
160     }
161 
setOrientation(int orientation)162     public void setOrientation(int orientation) {
163         if (isShowing()) return;
164         mOrientation = orientation;
165 
166         int hPaddingRootView = mRootView.getPaddingLeft() + mRootView.getPaddingRight();
167         int vPaddingRootView = mRootView.getPaddingTop() + mRootView.getPaddingBottom();
168 
169         // Calculate the width and the height of the thumbnail. Reserve the
170         // space for paddings.
171         float maxWidth = mPreviewFrame.getWidth() - hPaddingRootView;
172         float maxHeight = mPreviewFrame.getHeight() - vPaddingRootView;
173         // Swap the width and height if it is portrait mode.
174         if (orientation == 90 || orientation == 270) {
175             float temp = maxWidth;
176             maxWidth = maxHeight;
177             maxHeight = temp;
178         }
179         float actualAspect = maxWidth / maxHeight;
180         float desiredAspect = (float) mBitmapWidth / mBitmapHeight;
181 
182         if (mMimeType.startsWith("video/")) {
183             desiredAspect = 4F / 3F;
184             mThumbnail.setScaleType(ImageView.ScaleType.CENTER_CROP);
185         } else {
186             mThumbnail.setScaleType(ImageView.ScaleType.FIT_CENTER);
187         }
188 
189         LayoutParams params = mThumbnail.getLayoutParams();
190         if (actualAspect > desiredAspect) {
191             params.width = Math.round(maxHeight * desiredAspect);
192             params.height = Math.round(maxHeight);
193         } else {
194             params.width = Math.round(maxWidth);
195             params.height = Math.round(maxWidth / desiredAspect);
196         }
197         mThumbnail.setLayoutParams(params);
198 
199         if (mThumbnailRotateLayout != null) mThumbnailRotateLayout.setOrientation(orientation);
200 
201         int count = mShareList.getChildCount();
202         for (int i = 0; i < count; i++) {
203             ViewGroup f = (ViewGroup) mShareList.getChildAt(i);
204             RotateLayout r = (RotateLayout) f.findViewById(R.id.share_icon_rotate_layout);
205             r.setOrientation(orientation);
206         }
207 
208         mGotoGalleryRotate.setOrientation(orientation);
209     }
210 
211     @Override
showAtLocation(View parent, int gravity, int x, int y)212     public void showAtLocation(View parent, int gravity, int x, int y) {
213         super.showAtLocation(parent, gravity, x, y);
214         // Inform other popup to dismiss if exit
215         PopupManager.getInstance(mContext).notifyShowPopup(null);
216     }
217 
218     @Override
onClick(View v)219     public void onClick(View v) {
220         switch (v.getId()) {
221             case R.id.goto_gallery_button:
222             case R.id.thumbnail_image_frame:
223                 Util.viewUri(mUri, mContext);
224                 break;
225         }
226     }
227 
228     @Override
onTouch(View v, MotionEvent event)229     public boolean onTouch(View v, MotionEvent event) {
230         if (event.getAction() == MotionEvent.ACTION_DOWN) {
231             dismiss();
232             return true;
233         }
234         return false;
235     }
236 
createShareMenu()237     public void createShareMenu() {
238         PackageManager packageManager = mContext.getPackageManager();
239         List<ResolveInfo> infos = packageManager.queryIntentActivities(
240                 new Intent(Intent.ACTION_SEND).setType(mMimeType), 0);
241 
242         ArrayList<HashMap<String, Object>> items = new ArrayList<HashMap<String, Object>>();
243         for (ResolveInfo info : infos) {
244             ComponentName component = new ComponentName(
245                     info.activityInfo.packageName, info.activityInfo.name);
246             HashMap<String, Object> map = new HashMap<String, Object>();
247             map.put(ADAPTER_COLUMN_ICON, info.loadIcon(packageManager));
248             items.add(map);
249             mComponent.add(component);
250         }
251 
252         // On phone UI, we have to know how many icons in the grid view before
253         // the view is measured.
254         if (mActivityOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
255             mShareList.setNumColumns(items.size());
256             int width = mContext.getResources().getDimensionPixelSize(R.dimen.share_item_width);
257             mShareList.setColumnWidth(width);
258         }
259 
260         SimpleAdapter listItemAdapter = new MySimpleAdapter(mContext, items,
261                 R.layout.share_icon,
262                 new String[] {ADAPTER_COLUMN_ICON},
263                 new int[] {R.id.icon});
264 
265         listItemAdapter.setViewBinder(mViewBinder);
266         mShareList.setAdapter(listItemAdapter);
267         mShareList.setOnItemClickListener(this);
268     }
269 
getUri()270     public Uri getUri() {
271         return mUri;
272     }
273 
274     @Override
onItemClick(AdapterView<?> parent, View view, int index, long id)275     public void onItemClick(AdapterView<?> parent, View view, int index, long id) {
276         Intent intent = new Intent(Intent.ACTION_SEND);
277         intent.setType(mMimeType);
278         intent.putExtra(Intent.EXTRA_STREAM, mUri);
279         intent.setComponent(mComponent.get(index));
280         mContext.startActivity(intent);
281     }
282 }
283