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