天天看点

Camera Rule总结

概述

Rule 是Camera当中用于调控设置的一种方法,例如:相机中的手势拍照和美颜不能同时打开,此时就需要将这两个参数进行关联,当其中一个开启时,另一个需要关闭,且不能进行设置。而rule则能够很方便完成这一关联。

rule指的是CommonRule.java这个类,继承于IsettingRule()

其中主要的方法有以下几个:CommonRule(),execute()和addLimitation()以及在各个SettingItem中的addOverrideRecord()

CommonRule()

public CommonRule(String conditionKey, String resultKey,
            ICameraDeviceManager cameraDeviceManager, SettingGenerator settingGenerator) {
        mConditionKey = conditionKey;
        mResultKey = resultKey;
        mICameraDeviceManager = cameraDeviceManager;
        mSettingGenerator = settingGenerator;
    }
           

该函数为CommonRule的构造函数,传入了4个参数,conditionKey为规则的起因设置,resultKey为规则的作用设置。后两个参数在此类中只用于获取特定参数,就不做详细介绍了。

addLimitation()

public void addLimitation(String condition, List<String> result, MappingFinder mappingFinder) {
        mConditions.add(condition);
        mResults.add(result);
        mMappingFinder.add(mappingFinder);
    }
           

该函数用于添加限定条件,condition为条件值,即conditionKey的判断值,result为结果值,即满足conditionKey的值为condition设置resultKey的值。mappingFinder

执行一些逻辑从结果数组中找出结果值。

execute()

这个函数比较重要,在下方的调用中分析。

加载

当相机启动时,SettingCtrl会通过CreateRules()方法进行创建和加载rule。

创建通过三个方法完成:createRuleFromResctrictionMatrix(),createRuleFromRestrictions()和createRuleFromScene()

createRuleFromResctrictionMatrix()

通过settingDateBase中的MATRIX_RESTRICTION_STATE来创建规则,MATRIX_RESTRICTION_STATE是一个二维整形数组,包含了很多如下的整形数组:

//STATE_D0 disalbe
//STATE_E0 enalbe
//STATE_R0-R7 reset value 0-7
MATRIX_RESTRICTION_STATE[SettingConstants.ROW_SETTING_FLASH] = new int[]{
    STATE_E0, STATE_R0, STATE_R0, STATE_R0, STATE_E0, STATE_E0,
    STATE_E0, STATE_R0, STATE_E0, STATE_R0, STATE_R0};
           

其中数组中的不同位置分别表示该参数在不同模式下的状态,而位置是由settingDateBase中的RESTRCTION_SETTING_INDEX来规定的。

通过settingDateBase.getSettingResetValue()获取上述int的对应value:STATE_E0->null,STATE_D0->”disable-value”,STATE_R0-R7->reset value 0-7。

rule = new CommonRule(conditionKey,resultKey,mICameraDeviceManager,mSettingGenerator);
rule.addLimitation("on",values,null);
mRuleMatrix[conditionSettingIndex][row] = rule;
           

然后据此生成CommonRule,存入mRuleMatrix中,存放索引为mRuleMatrix[conditionSettngIndex][resuleSettingIndex]。如上例第二列,conditionSettngIndex为RESTRCTION_SETTING_INDEX[1]即SettingConstants.ROW_SETTING_HDR,rule为SettingConstants.ROW_SETTING_FLASH。 values = {“off”}。即当FLASH设置为on时,HDR置为off。

createRuleFromRestrictions()

通过SettingDataBase中的RESTRICTIOINS来创建规则,RESTRICTIOINS是一个Restriction集合。

new Restriction(SettingConstants.ROW_SETTING_SLOW_MOTION)
.setValue("on")
.setRestrictions(
    new Restriction(SettingConstants.ROW_SETTING_VIDEO_STABLE)
    .setEnable(false)
    .setValue("off")),
           
if(mRuleMatrix[conditionSettingIndex][resultSettingId] == null){
    rule = new CommonRule(conditionKey,resultKey,mICameraDeviceManager,mSettingGenerator);
    mRuleMatrix[conditionSettingIndex][resultSettingId] = rule;
} else {
    rule = mRuleMatrix[conditionSettingIndex][resultSettingId];
}
for (int k = 0; k < conditionValues.size(); k++){
   rule.addLimitation(conditionValues.get(k), resultValues,mappingFinder);
}

           

遍历RESTRICTIOINS,判断在createRuleFromResctrictionMatrix()中是否有添加过rule,如果有则进行追加,如果没有则创建,据此将所有的rule存入mRuleMatrix中,存放索引为mRuleMatrix[conditionSettngIndex][resuleSettingIndex],上例中conditionSettngIndex = SettingConstants.ROW_SETTING_SLOW_MOTION。resuleSettingIndex = SettingConstants.ROW_SETTING_VIDEO_STABLE。conditionValues.size = 1,conditionValues.get(k) = “on”,resultValues = “off”,mappingFinder = null。即SLOW_MOTION设置为on时,video_stable置为off。

createRuleFromScene()

createRuleFromScene()的加载方式与createRuleFromResctrictionMatrix()类似,区别在于此规则是是根据SettingDateBase中的MATRIX_SCENE_STATE来创建的。

conditionKey为SettingConstants.KEY_SCENE_MODE。不同的列分别代表了KEY_SCENE_MODE设置的不同值。其他的与createRuleFromResctrictionMatrix()差别不大,就不一一概述了。

addOverrideRecord()

public void addOverrideRecord(String key, Record record) {
        mOverrideRecord.put(key, record);
    }
           
public Record(String value, String overrideValue) {
            mValue = value;
            mOverrideValue = overrideValue;
        }
           

每个SettingItem中均存在一个Record集合mOverrideRecord,addOverrideRecord中包含两个参数:key,一般为上文所说的conditionKey;Record中存储两个参数:value ,overrideValue。

调用

rule的调用是通过rule.execute()来处理的,并调用setResultSettingValue来对resultKey进行设置。

execute()

execute()是通过目前的conditionValues和resultValues,进行一些逻辑处理。得到result和overrideValue进行setResultSettingValue()操作,setResultSettingValue()通过settingType的不同调用不同的方式使resultValue能正确的设置。

@Override
    public void execute() {
        mConditionSetting = mSettingGenerator.getSettingItem(mConditionKey);
        mResultSetting = mSettingGenerator.getSettingItem(mResultKey);

        String conditionSettingValue = mConditionSetting.getValue();
        //判断目前conditionSettingValue的值在mConditions中序列,如果没有返回-1
        int index = conditionSatisfied(conditionSettingValue);
        String resultValue = mResultSetting.getValue();
        //获取resultSetting的类型,在SettingDateBase里配置
        int type = mResultSetting.getType();
        // if index is equal with -1, means no condition is satisfied.
        Log.i(TAG, "[execute], conditionSetting:" + mConditionKey + ", conditionValue:" +
                "" + conditionSettingValue + ", resultSetting:" + mResultKey + ", " +
                "resultSettingValue:" + resultValue + ", index = " + index);
        //当conditionSettingValue不在mConditions序列中。
        if (index == -) {
            int overrideCount = mResultSetting.getOverrideCount();
            Record record = mResultSetting.getOverrideRecord(mConditionKey);
            //判断是否是通过SettingItem.addOverrideRecord()添加的规则。如果没有则返回
            if (record == null) {
                return;
            }
            Log.i(TAG, "overrideCount:" + overrideCount);
            mResultSetting.removeOverrideRecord(mConditionKey);
            overrideCount--;
            if (overrideCount > ) {
                Record topRecord = mResultSetting.getTopOverrideRecord();
                if (topRecord != null) {
                    if (mResultSetting.isEnable()) {
                        String value = topRecord.getValue();
                        String overrideValue = topRecord.getOverrideValue();
                        // may be the setting's value is changed, the value in record is old.
                        ListPreference pref = mResultSetting.getListPreference();
                        if (pref != null && SettingUtils.isBuiltList(overrideValue)) {
                            pref.setEnabled(true);

                            String prefValue =  pref.getValue();

                            List<String> list = SettingUtils.getEnabledList(overrideValue);
                            if (list.contains(prefValue)) {
                                if (!prefValue.equals(value)) {
                                    String[] values = new String[list.size()];
                                    overrideValue = SettingUtils.buildEnableList(
                                            list.toArray(values), prefValue);
                                }
                                value = prefValue;
                            }
                        }
                        setResultSettingValue(type, value, overrideValue, mRestoreSupported);
                    }
                }
            } else {
                ListPreference pref = null;
                switch (type) {
                case SettingConstants.NEITHER_IN_PARAMETER_NOR_IN_PREFERENCE:
                case SettingConstants.ONLY_IN_PARAMETER:
                    resultValue = mResultSetting.getDefaultValue();
                    break;

                case SettingConstants.ONLY_IN_PEFERENCE:
                case SettingConstants.BOTH_IN_PARAMETER_AND_PREFERENCE:
                    pref = mResultSetting.getListPreference();
                    if (pref != null) {
                        resultValue = pref.getValue();
                    }
                    break;

                default:
                    break;
                }

                String overrideValue = null;
                if (mResultSetting.isEnable()) {
                    if (mRestoreSupported == false) {
                        if (pref != null) {
                            pref.setEnabled(true);
                        }
                        mRestoreSupported = true;
                    } else {
                        setResultSettingValue(type, resultValue, overrideValue, mRestoreSupported);
                    }
                }
            }
        } else {
            //获取addlimitation中传入的result
            List<String> resultValues = mResults.get(index);
            //主要是对resultValue为RESET_STATE_VALUE_DISABLE或key为KEY_PICTURE_SIZE进行处理,其余的直接返回resultItem的value。
            List<String> resultValuesAfterFilter = filterUnsupportedValue(resultValues, mResultKey);
            // just get the first value temporary
            //根据resultValues返回处理后的值
            resultValue = getResultSettingValue(resultValuesAfterFilter, index);
            String overrideValue = null;
            //D0
            if (SettingUtils.RESET_STATE_VALUE_DISABLE.equals(resultValue)) {
                overrideValue = SettingUtils.RESET_STATE_VALUE_DISABLE;
                mRestoreSupported = false;
                resultValue = mResultSetting.getValue();
            } else if (resultValues.size() <= ) {
                overrideValue = resultValue;
                mRestoreSupported = true;
            } else {
                String[] values = new String[resultValuesAfterFilter.size()];
                overrideValue = SettingUtils.buildEnableList(
                        resultValuesAfterFilter.toArray(values), resultValue);
                mRestoreSupported = true;
            }
            if (mResultSetting.isEnable()) {
                setResultSettingValue(type, resultValue, overrideValue, true);
            }

            Record record = mResultSetting.new Record(resultValue, overrideValue);
            mResultSetting.addOverrideRecord(mConditionKey, record);
        }
    }
           

总结

Camera Rule中通过一些数组来调用不同的规则,从而使大量的规则能够以一种较为简单的方式进行设置。