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 100 /** 101 * Computes the list of picture sizes that should be displayed by settings. 102 * <p> 103 * For this it will open the camera devices to determine the available 104 * sizes, if the sizes are not already cached. This is to be compatible with 105 * devices running Camera API 1. 106 * <p> 107 * We then calculate the resolutions that should be available and in the end 108 * filter it in case a resolution is on the blacklist for this device. 109 */ computePictureSizes()110 public PictureSizes computePictureSizes() { 111 List<Size> backCameraSizes = computeSizesForCamera(SettingsUtil.CAMERA_FACING_BACK); 112 List<Size> frontCameraSizes = computeSizesForCamera(SettingsUtil.CAMERA_FACING_FRONT); 113 Optional<SelectedVideoQualities> videoQualitiesBack = 114 computeQualitiesForCamera(SettingsUtil.CAMERA_FACING_BACK); 115 Optional<SelectedVideoQualities> videoQualitiesFront = 116 computeQualitiesForCamera(SettingsUtil.CAMERA_FACING_FRONT); 117 return new PictureSizes(backCameraSizes, frontCameraSizes, videoQualitiesBack, 118 videoQualitiesFront); 119 } 120 computeSizesForCamera(CameraDeviceSelector facingSelector)121 private List<Size> computeSizesForCamera(CameraDeviceSelector facingSelector) { 122 List<Size> sizes; 123 int cameraId = SettingsUtil.getCameraId(mCameraDeviceInfo, facingSelector); 124 if (cameraId >= 0) { 125 if (mCachedOnly) { 126 sizes = CameraPictureSizesCacher.getCachedSizesForCamera(cameraId, mContext) 127 .orNull(); 128 } else { 129 sizes = CameraPictureSizesCacher.getSizesForCamera(cameraId, mContext); 130 } 131 132 if (sizes != null) { 133 sizes = ResolutionUtil 134 .getDisplayableSizesFromSupported(sizes, 135 facingSelector == SettingsUtil.CAMERA_FACING_BACK); 136 String blacklisted = GservicesHelper 137 .getBlacklistedResolutionsBack(mContentResolver); 138 sizes = ResolutionUtil.filterBlackListedSizes(sizes, blacklisted); 139 return sizes; 140 } 141 } 142 return new ArrayList<>(0); 143 } 144 computeQualitiesForCamera( CameraDeviceSelector facingSelector)145 private Optional<SelectedVideoQualities> computeQualitiesForCamera( 146 CameraDeviceSelector facingSelector) { 147 int cameraId = SettingsUtil.getCameraId(mCameraDeviceInfo, facingSelector); 148 if (cameraId >= 0) { 149 // This is guaranteed not to be null/absent. 150 return Optional.of(SettingsUtil.getSelectedVideoQualities(cameraId)); 151 } 152 return Optional.absent(); 153 } 154 } 155