Home | History | Annotate | Download | only in config
      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.one.config;
     18 
     19 import android.content.ContentResolver;
     20 import android.hardware.camera2.CameraCharacteristics;
     21 
     22 import com.android.camera.app.MemoryManager;
     23 import com.android.camera.debug.Log;
     24 import com.android.camera.one.config.OneCameraFeatureConfig.CaptureSupportLevel;
     25 import com.android.camera.one.config.OneCameraFeatureConfig.HdrPlusSupportLevel;
     26 import com.android.camera.util.ApiHelper;
     27 import com.android.camera.util.GcamHelper;
     28 import com.android.camera.util.GservicesHelper;
     29 import com.google.common.base.Function;
     30 import com.google.common.base.Optional;
     31 
     32 /**
     33  * Creates the OneCamera feature configurations for the GoogleCamera app.
     34  */
     35 public class OneCameraFeatureConfigCreator {
     36     private static final Log.Tag TAG = new Log.Tag("OneCamFtrCnfgCrtr");
     37 
     38     /**
     39      * Create the default camera feature config.
     40      */
     41     public static OneCameraFeatureConfig createDefault(ContentResolver contentResolver,
     42             MemoryManager memoryManager) {
     43         // Enable CaptureModule on all M devices.
     44         boolean useCaptureModule = true;
     45         Log.i(TAG, "CaptureModule? " + useCaptureModule);
     46 
     47         // HDR+ has multiple levels of support.
     48         HdrPlusSupportLevel hdrPlusSupportLevel =
     49                 GcamHelper.determineHdrPlusSupportLevel(contentResolver, useCaptureModule);
     50         return new OneCameraFeatureConfig(useCaptureModule,
     51                 buildCaptureModuleDetector(contentResolver),
     52                 hdrPlusSupportLevel,
     53                 memoryManager.getMaxAllowedNativeMemoryAllocation(),
     54                 GservicesHelper.getMaxAllowedImageReaderCount(contentResolver));
     55     }
     56 
     57     private static Function<CameraCharacteristics, CaptureSupportLevel> buildCaptureModuleDetector(
     58             final ContentResolver contentResolver) {
     59         return new Function<CameraCharacteristics, CaptureSupportLevel>() {
     60             @Override
     61             public CaptureSupportLevel apply(CameraCharacteristics characteristics) {
     62                 // If a capture support level override exists, use it. Otherwise
     63                 // dynamically check the capabilities of the current device.
     64                 Optional<CaptureSupportLevel> override =
     65                         getCaptureSupportLevelOverride(characteristics, contentResolver);
     66                 if (override.isPresent()) {
     67                     Log.i(TAG, "Camera support level override: " + override.get().name());
     68                     return override.get();
     69                 }
     70 
     71                 Integer supportedLevel = characteristics
     72                         .get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
     73 
     74                 // A hardware level should always be supported, so we should
     75                 // never have to return here. If no hardware level is supported
     76                 // on a LEGACY device, the LIMITED_JPEG fallback will not work.
     77                 if (supportedLevel == null) {
     78                     Log.e(TAG, "Device does not report supported hardware level.");
     79                     return CaptureSupportLevel.LIMITED_JPEG;
     80                 }
     81 
     82                 // LEGACY_JPEG is the ONLY mode that is supported on LEGACY
     83                 // devices.
     84                 if (supportedLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
     85                     return CaptureSupportLevel.LEGACY_JPEG;
     86                 }
     87 
     88                 // No matter if L or L MR1, the N5 does not currently support
     89                 // ZSL due to HAL bugs. The latest one causes random preview
     90                 // freezes even on MR1, see b/19565931.
     91                 if (ApiHelper.IS_NEXUS_5) {
     92                     return CaptureSupportLevel.LIMITED_JPEG;
     93                 }
     94 
     95                 if (ApiHelper.IS_NEXUS_6) {
     96                     if (ApiHelper.isLMr1OrHigher()) {
     97                         // Although front-facing cameras on the N6 (and N5) are not advertised as
     98                         // FULL, they can do ZSL. We might want to change the check for ZSL
     99                         // according to b/19625916.
    100                         return CaptureSupportLevel.ZSL;
    101                     } else {
    102                         // On a non-LEGACY N6 (or N5) prior to Lollipop MR1 we fall back to
    103                         // LIMITED_JPEG due to HAL bugs.
    104                         return CaptureSupportLevel.LIMITED_JPEG;
    105                     }
    106                 }
    107 
    108                 // On FULL devices starting with L-MR1 we can run ZSL.
    109                 if (supportedLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL) {
    110                     return CaptureSupportLevel.ZSL;
    111                 }
    112 
    113                 // On LIMITED devices starting with L-MR1 we run a simple YUV
    114                 // capture mode.
    115                 if (supportedLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED) {
    116                     return CaptureSupportLevel.LIMITED_YUV;
    117                 }
    118 
    119                 // We should never get here. If we do, let's fall back to a mode
    120                 // that should work on all non-LEGACY devices.
    121                 Log.e(TAG, "Unknown support level: " + supportedLevel);
    122                 return CaptureSupportLevel.LIMITED_JPEG;
    123             }
    124         };
    125     }
    126 
    127     /**
    128      * @return If an override exits, this returns the capture support hardware
    129      *         level that should be used on this device.
    130      */
    131     private static Optional<CaptureSupportLevel> getCaptureSupportLevelOverride(
    132             CameraCharacteristics cameraCharacteristics, ContentResolver contentResolver) {
    133         Integer facing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
    134         if (facing == null) {
    135             Log.e(TAG, "Camera not facing anywhere.");
    136             return Optional.absent();
    137         }
    138 
    139         switch (facing) {
    140             case CameraCharacteristics.LENS_FACING_BACK: {
    141                 int override = GservicesHelper.getCaptureSupportLevelOverrideBack(contentResolver);
    142                 return CaptureSupportLevel.fromFlag(override);
    143             }
    144             case CameraCharacteristics.LENS_FACING_FRONT: {
    145                 int override = GservicesHelper.getCaptureSupportLevelOverrideFront(contentResolver);
    146                 return CaptureSupportLevel.fromFlag(override);
    147             }
    148             default:
    149                 Log.e(TAG, "Not sure where camera is facing to.");
    150                 return Optional.absent();
    151         }
    152     }
    153 }
    154