1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/* 2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2016 The Android Open Source Project 3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License"); 5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License. 6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at 7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * http://www.apache.org/licenses/LICENSE-2.0 9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software 11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS, 12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and 14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License. 15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.dialer.callcomposer.cameraui; 18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context; 20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Canvas; 21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.hardware.Camera; 22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Bundle; 23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Parcelable; 24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.util.AttributeSet; 25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.ViewGroup; 26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.widget.FrameLayout; 27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.callcomposer.camera.CameraManager; 28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.callcomposer.camera.HardwareCameraPreview; 29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.callcomposer.camera.SoftwareCameraPreview; 30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.common.LogUtil; 31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/** Used to display the view of the camera. */ 33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class CameraMediaChooserView extends FrameLayout { 34ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private static final String STATE_CAMERA_INDEX = "camera_index"; 35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private static final String STATE_SUPER = "super"; 36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // True if we have at least queued an update to the view tree to support software rendering 38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // fallback 39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private boolean mIsSoftwareFallbackActive; 40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public CameraMediaChooserView(final Context context, final AttributeSet attrs) { 42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian super(context, attrs); 43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected Parcelable onSaveInstanceState() { 47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final Bundle bundle = new Bundle(); 48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian bundle.putParcelable(STATE_SUPER, super.onSaveInstanceState()); 49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final int cameraIndex = CameraManager.get().getCameraIndex(); 50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian LogUtil.i("CameraMediaChooserView.onSaveInstanceState", "saving camera index:" + cameraIndex); 51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian bundle.putInt(STATE_CAMERA_INDEX, cameraIndex); 52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return bundle; 53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected void onRestoreInstanceState(final Parcelable state) { 57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!(state instanceof Bundle)) { 58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return; 59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final Bundle bundle = (Bundle) state; 62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final int cameraIndex = bundle.getInt(STATE_CAMERA_INDEX); 63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian super.onRestoreInstanceState(bundle.getParcelable(STATE_SUPER)); 64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian LogUtil.i( 66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian "CameraMediaChooserView.onRestoreInstanceState", "restoring camera index:" + cameraIndex); 67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (cameraIndex != -1) { 68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian CameraManager.get().selectCameraByIndex(cameraIndex); 69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian resetState(); 71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void resetState() { 75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian CameraManager.get().selectCamera(Camera.CameraInfo.CAMERA_FACING_BACK); 76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected void onDraw(final Canvas canvas) { 80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian super.onDraw(canvas); 81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // If the canvas isn't hardware accelerated, we have to replace the HardwareCameraPreview 82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // with a SoftwareCameraPreview which supports software rendering 83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!canvas.isHardwareAccelerated() && !mIsSoftwareFallbackActive) { 84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mIsSoftwareFallbackActive = true; 85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Post modifying the tree since we can't modify the view tree during a draw pass 86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian post( 87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian new Runnable() { 88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void run() { 90ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final HardwareCameraPreview cameraPreview = 91ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian (HardwareCameraPreview) findViewById(R.id.camera_preview); 92ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (cameraPreview == null) { 93ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return; 94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final ViewGroup parent = ((ViewGroup) cameraPreview.getParent()); 96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final int index = parent.indexOfChild(cameraPreview); 97ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final SoftwareCameraPreview softwareCameraPreview = 98ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian new SoftwareCameraPreview(getContext()); 99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Be sure to remove the hardware view before adding the software view to 100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // prevent having 2 camera previews active at the same time 101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian parent.removeView(cameraPreview); 102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian parent.addView(softwareCameraPreview, index); 103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian }); 105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian} 108