1 /*
2  * Copyright 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 
17 package com.android.cts.verifier.managedprovisioning;
18 
19 import android.app.Dialog;
20 import android.app.DialogFragment;
21 import android.content.DialogInterface;
22 import android.graphics.Bitmap;
23 import android.graphics.Matrix;
24 import android.media.ExifInterface;
25 import android.net.Uri;
26 import android.media.MediaPlayer;
27 import android.media.MediaPlayer.OnPreparedListener;
28 import android.os.Bundle;
29 import android.util.Log;
30 import android.view.View;
31 import android.view.View.OnClickListener;
32 import android.widget.Button;
33 import android.widget.ImageView;
34 import android.widget.Toast;
35 import android.widget.VideoView;
36 import android.view.Display;
37 import android.graphics.BitmapFactory;
38 import android.graphics.Point;
39 import android.content.ContentResolver;
40 import com.android.cts.verifier.R;
41 
42 import java.io.File;
43 import java.io.FileInputStream;
44 import java.io.IOException;
45 import java.io.InputStream;
46 
47 /**
48  * This dialog shows/plays an image, video or audio uri.
49  */
50 public class ByodPresentMediaDialog extends DialogFragment {
51     static final String TAG = "ByodPresentMediaDialog";
52 
53     private static final String KEY_VIDEO_URI = "video";
54     private static final String KEY_IMAGE_FILE = "image_file";
55     private static final String KEY_AUDIO_URI = "audio";
56 
57     private Bitmap scaled = null;
58     /**
59      * Get a dialogFragment showing an image.
60      */
newImageInstance(File file)61     public static ByodPresentMediaDialog newImageInstance(File file) {
62         ByodPresentMediaDialog dialog = new ByodPresentMediaDialog();
63         Bundle args = new Bundle();
64         args.putSerializable(KEY_IMAGE_FILE, file);
65         dialog.setArguments(args);
66         return dialog;
67     }
68 
69     /**
70      * Get a dialogFragment playing a video.
71      */
newVideoInstance(Uri uri)72     public static ByodPresentMediaDialog newVideoInstance(Uri uri) {
73         ByodPresentMediaDialog dialog = new ByodPresentMediaDialog();
74         Bundle args = new Bundle();
75         args.putParcelable(KEY_VIDEO_URI, uri);
76         dialog.setArguments(args);
77         return dialog;
78     }
79 
80     /**
81      * Get a dialogFragment playing audio.
82      */
newAudioInstance(Uri uri)83     public static ByodPresentMediaDialog newAudioInstance(Uri uri) {
84         ByodPresentMediaDialog dialog = new ByodPresentMediaDialog();
85         Bundle args = new Bundle();
86         args.putParcelable(KEY_AUDIO_URI, uri);
87         dialog.setArguments(args);
88         return dialog;
89     }
90 
calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)91     private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight){
92         // Raw height and width of image
93         final int height = options.outHeight;
94         final int width = options.outWidth;
95         if(reqWidth <= 0 || reqHeight <= 0) {
96            return 1;
97         }
98         return Math.max(height/reqHeight, width/reqWidth) + 1;
99     }
100 
101     @Override
onCreateDialog(Bundle savedInstanceState)102     public Dialog onCreateDialog(Bundle savedInstanceState) {
103         final Dialog dialog = new Dialog(getActivity());
104         dialog.setContentView(R.layout.byod_present_media);
105 
106         Button dismissButton = (Button) dialog.findViewById(R.id.dismissButton);
107         dismissButton.setOnClickListener(new View.OnClickListener() {
108             public void onClick(View v) {
109                 dismiss();
110                 ((DialogCallback) getActivity()).onDialogClose();
111             }
112         });
113 
114         Bundle arguments = getArguments();
115 
116         // Initially all video and image specific UI is invisible.
117         if (arguments.containsKey(KEY_VIDEO_URI)) {
118             // Show video UI.
119             dialog.setTitle(getString(R.string.provisioning_byod_verify_video_title));
120 
121             Uri uri = (Uri) getArguments().getParcelable(KEY_VIDEO_URI);
122             final VideoView videoView = (VideoView) dialog.findViewById(R.id.videoView);
123             videoView.setVisibility(View.VISIBLE);
124             videoView.setVideoURI(uri);
125 
126             Button playButton = (Button) dialog.findViewById(R.id.playButton);
127             playButton.setVisibility(View.VISIBLE);
128             playButton.setOnClickListener(new View.OnClickListener() {
129                 public void onClick(View v) {
130                     videoView.start();
131                 }
132             });
133         } else if (arguments.containsKey(KEY_IMAGE_FILE)) {
134             // Show image UI.
135 
136             dialog.setTitle(getString(R.string.provisioning_byod_verify_image_title));
137             File imageFile = (File) getArguments().getSerializable(KEY_IMAGE_FILE);
138 
139             ImageView imageView = (ImageView) dialog.findViewById(R.id.imageView);
140             imageView.setVisibility(View.VISIBLE);
141 
142             try {
143                 InputStream input = null;
144                 int orientationInDegree = getOrientationInDegreeFromImage(imageFile);
145                 Log.d(TAG, "orientationInDegree: " + orientationInDegree);
146                 input = new FileInputStream(imageFile);
147                 BitmapFactory.Options options = new BitmapFactory.Options();
148                 options.inJustDecodeBounds = true;
149                 BitmapFactory.decodeStream(input, null, options);
150                 //scale the picture
151                 Display display = getActivity().getWindowManager().getDefaultDisplay();
152                 Point size = new Point();
153                 display.getSize(size);
154                 int reqWidth = size.x;
155                 int reqHeight = size.y;
156                 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
157 
158                 options.inJustDecodeBounds = false;
159                 input.close();
160                 input = new FileInputStream(imageFile);
161                 scaled = BitmapFactory.decodeStream(input, null, options);
162                 if (orientationInDegree != 0) {
163                     Matrix matrix = new Matrix();
164                     matrix.postRotate(orientationInDegree);
165                     scaled = Bitmap.createBitmap(scaled, 0, 0, scaled.getWidth(),
166                             scaled.getHeight(), matrix, true);
167                 }
168                 input.close();
169                 imageView.setImageBitmap(scaled);
170             } catch (IOException e) {
171                 Log.e(TAG, "Cannot get image.", e);
172                 Toast.makeText(getActivity(), R.string.provisioning_byod_capture_image_error,
173                         Toast.LENGTH_SHORT).show();
174                 getActivity().finish();
175             }
176 
177         } else if (arguments.containsKey(KEY_AUDIO_URI)) {
178             // Show audio playback UI.
179             dialog.setTitle(getString(R.string.provisioning_byod_verify_audio_title));
180 
181             Uri uri = (Uri) getArguments().getParcelable(KEY_AUDIO_URI);
182             final MediaPlayer mediaPlayer = new MediaPlayer();
183             final Button playButton = (Button) dialog.findViewById(R.id.playButton);
184             playButton.setVisibility(View.VISIBLE);
185             playButton.setEnabled(false);
186 
187             try {
188                 mediaPlayer.setDataSource(getActivity(), uri);
189                 mediaPlayer.prepare();
190             } catch (IllegalArgumentException|SecurityException|IllegalStateException
191                     |IOException e) {
192                 Log.e(TAG, "Cannot play given audio with media player.", e);
193                 Toast.makeText(getActivity(), R.string.provisioning_byod_capture_media_error,
194                         Toast.LENGTH_SHORT).show();
195                 getActivity().finish();
196             }
197 
198             mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
199                 @Override
200                 public void onPrepared(MediaPlayer mp) {
201                     playButton.setEnabled(true);
202                     playButton.setOnClickListener(new View.OnClickListener() {
203                         public void onClick(View v) {
204                             mediaPlayer.start();
205                         }
206                     });
207                 }
208             });
209         }
210 
211         return dialog;
212     }
213 
getOrientationInDegreeFromImage(File imageFile)214     private static int getOrientationInDegreeFromImage(File imageFile) throws IOException {
215         ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath());
216         int exifOrientation =
217                 exifInterface.getAttributeInt(
218                         ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
219         return exifOrientationToDegree(exifOrientation);
220     }
221 
exifOrientationToDegree(int exifOrientation)222     private static int exifOrientationToDegree(int exifOrientation) {
223         switch (exifOrientation) {
224             case ExifInterface.ORIENTATION_ROTATE_90:
225                 return 90;
226             case ExifInterface.ORIENTATION_ROTATE_180:
227                 return 180;
228             case ExifInterface.ORIENTATION_ROTATE_270:
229                 return 270;
230         }
231         return 0;
232     }
233 
234     @Override
onCancel(DialogInterface dialog)235     public void onCancel(DialogInterface dialog) {
236         ((DialogCallback) getActivity()).onDialogClose();
237     }
238 
239     @Override
onDestroyView()240     public void onDestroyView() {
241         if(scaled!=null){
242             scaled.recycle();
243         }
244         super.onDestroyView();
245     }
246     public interface DialogCallback {
onDialogClose()247         public abstract void onDialogClose();
248     }
249 }
250