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 17 package com.android.camera.settings; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 22 import com.android.camera.settings.SettingsUtil.CameraDeviceSelector; 23 import com.android.camera.settings.SettingsUtil.SelectedVideoQualities; 24 import com.android.camera.util.GservicesHelper; 25 import com.android.camera.util.Size; 26 import com.android.ex.camera2.portability.CameraAgentFactory; 27 import com.android.ex.camera2.portability.CameraDeviceInfo; 28 import com.google.common.base.Optional; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 33 import javax.annotation.Nonnull; 34 import javax.annotation.ParametersAreNonnullByDefault; 35 36 /** 37 * Loads the camera picture sizes that can be set by the user. 38 * <p> 39 * This class is compatible with pre-Lollipop since it uses the compatibility 40 * layer to access the camera metadata. 41 */ 42 @ParametersAreNonnullByDefault 43 public class PictureSizeLoader { 44 /** 45 * Holds the sizes for the back- and front cameras which will be available 46 * to the user for selection form settings. 47 */ 48 @ParametersAreNonnullByDefault 49 public static class PictureSizes { 50 public final List<Size> backCameraSizes; 51 public final List<Size> frontCameraSizes; 52 public final Optional<SelectedVideoQualities> videoQualitiesBack; 53 public final Optional<SelectedVideoQualities> videoQualitiesFront; 54 PictureSizes(List<Size> backCameraSizes, List<Size> frontCameraSizes, Optional<SelectedVideoQualities> videoQualitiesBack, Optional<SelectedVideoQualities> videoQualitiesFront)55 PictureSizes(List<Size> backCameraSizes, 56 List<Size> frontCameraSizes, 57 Optional<SelectedVideoQualities> videoQualitiesBack, 58 Optional<SelectedVideoQualities> videoQualitiesFront) { 59 this.backCameraSizes = backCameraSizes; 60 this.frontCameraSizes = frontCameraSizes; 61 this.videoQualitiesBack = videoQualitiesBack; 62 this.videoQualitiesFront = videoQualitiesFront; 63 } 64 } 65 66 private final Context mContext; 67 private final ContentResolver mContentResolver; 68 private final CameraDeviceInfo mCameraDeviceInfo; 69 private final boolean mCachedOnly; 70 71 /** 72 * Initializes a new picture size loader. 73 * <p> 74 * This constructor will default to using the camera devices if the size 75 * values were not found in cache. 76 * 77 * @param context used to load caches sizes from preferences. 78 */ PictureSizeLoader(Context context)79 public PictureSizeLoader(Context context) { 80 this(context, false); 81 } 82 83 /** 84 * Initializes a new picture size loader. 85 * 86 * @param context used to load caches sizes from preferences. 87 * @param cachedOnly if set to true, this will only check the cache for 88 * sizes. If the cache is empty, this will NOT attempt to open 89 * the camera devices in order to obtain the sizes. 90 */ PictureSizeLoader(Context context, boolean cachedOnly)91 public PictureSizeLoader(Context context, boolean cachedOnly) { 92 mContext = context; 93 mContentResolver = context.getContentResolver(); 94 mCameraDeviceInfo = CameraAgentFactory 95 .getAndroidCameraAgent(context, CameraAgentFactory.CameraApi.API_1) 96 .getCameraDeviceInfo(); 97 mCachedOnly = cachedOnly; 98 } 99 release()100 public void release(){ 101 CameraAgentFactory.recycle(CameraAgentFactory.CameraApi.API_1); 102 } 103 104 /** 105 * Computes the list of picture sizes that should be displayed by settings. 106 * <p> 107 * For this it will open the camera devices to determine the available 108 * sizes, if the sizes are not already cached. This is to be compatible with 109 * devices running Camera API 1. 110 * <p> 111 * We then calculate the resolutions that should be available and in the end 112 * filter it in case a resolution is on the blacklist for this device. 113 */ computePictureSizes()114 public PictureSizes computePictureSizes() { 115 List<Size> backCameraSizes = computeSizesForCamera(SettingsUtil.CAMERA_FACING_BACK); 116 List<Size> frontCameraSizes = computeSizesForCamera(SettingsUtil.CAMERA_FACING_FRONT); 117 Optional<SelectedVideoQualities> videoQualitiesBack = 118 computeQualitiesForCamera(SettingsUtil.CAMERA_FACING_BACK); 119 Optional<SelectedVideoQualities> videoQualitiesFront = 120 computeQualitiesForCamera(SettingsUtil.CAMERA_FACING_FRONT); 121 return new PictureSizes(backCameraSizes, frontCameraSizes, videoQualitiesBack, 122 videoQualitiesFront); 123 } 124 computeSizesForCamera(CameraDeviceSelector facingSelector)125 private List<Size> computeSizesForCamera(CameraDeviceSelector facingSelector) { 126 List<Size> sizes; 127 int cameraId = SettingsUtil.getCameraId(mCameraDeviceInfo, facingSelector); 128 if (cameraId >= 0) { 129 if (mCachedOnly) { 130 sizes = CameraPictureSizesCacher.getCachedSizesForCamera(cameraId, mContext) 131 .orNull(); 132 } else { 133 sizes = CameraPictureSizesCacher.getSizesForCamera(cameraId, mContext); 134 } 135 136 if (sizes != null) { 137 sizes = ResolutionUtil 138 .getDisplayableSizesFromSupported(sizes, 139 facingSelector == SettingsUtil.CAMERA_FACING_BACK); 140 String blacklisted = GservicesHelper 141 .getBlacklistedResolutionsBack(mContentResolver); 142 sizes = ResolutionUtil.filterBlackListedSizes(sizes, blacklisted); 143 return sizes; 144 } 145 } 146 return new ArrayList<>(0); 147 } 148 computeQualitiesForCamera( CameraDeviceSelector facingSelector)149 private Optional<SelectedVideoQualities> computeQualitiesForCamera( 150 CameraDeviceSelector facingSelector) { 151 int cameraId = SettingsUtil.getCameraId(mCameraDeviceInfo, facingSelector); 152 if (cameraId >= 0) { 153 // This is guaranteed not to be null/absent. 154 return Optional.of(SettingsUtil.getSelectedVideoQualities(cameraId)); 155 } 156 return Optional.absent(); 157 } 158 } 159