概述
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 == -1) {
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 > 0) {
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() <= 1) {
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中通过一些数组来调用不同的规则,从而使大量的规则能够以一种较为简单的方式进行设置。