Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f53a027b authored by Jeremy Meyer's avatar Jeremy Meyer
Browse files

Add flag support to styles elements

Test: Automated
Bug: 329436914
Flag: EXEMPT Aconfig not supported on host tools
Change-Id: I3041ebbaf98a90527809b541df8885edfc70d035
parent a0811c0e
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.res.ApkAssets;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.FileUtils;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
@@ -151,6 +152,27 @@ public class ResourceFlaggingTest {
        mResources.getDrawable(R.drawable.removedpng);
    }

    @Test
    public void testDisabledStyleDoesntOverride() {
        TypedArray ta = mResources.newTheme().obtainStyledAttributes(
                R.style.style1, new int[] { android.R.attr.windowIsTranslucent});
        assertThat(ta.getBoolean(0, false)).isTrue();
    }

    @Test
    public void testEnabledStyleDoesOverride() {
        TypedArray ta = mResources.newTheme().obtainStyledAttributes(
                R.style.style2, new int[] { android.R.attr.windowIsTranslucent});
        assertThat(ta.getBoolean(0, false)).isTrue();
    }

    @Test
    public void testEnabledStyleItemDoesOverride() {
        TypedArray ta = mResources.newTheme().obtainStyledAttributes(
                R.style.style3, new int[] { android.R.attr.windowIsTranslucent});
        assertThat(ta.getBoolean(0, false)).isTrue();
    }

    private LayoutInflater getLayoutInflater() {
        ContextWrapper c = new ContextWrapper(mContext) {
            private LayoutInflater mInflater;
+22 −1
Original line number Diff line number Diff line
@@ -1529,13 +1529,34 @@ bool ResourceParser::ParseStyleItem(xml::XmlPullParser* parser, Style* style) {
  ResolvePackage(parser, &maybe_key.value());
  maybe_key.value().SetSource(source);

  auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag"));

  std::unique_ptr<Item> value = ParseXml(parser, 0, kAllowRawString);
  if (!value) {
    diag_->Error(android::DiagMessage(source) << "could not parse style item");
    return false;
  }

  if (flag) {
    if (options_.flag) {
      diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
                   << "Resource flag are not allowed both in the path and in the file");
      return false;
    }
    std::string error;
    auto flag_status = GetFlagStatus(flag, options_.feature_flag_values, &error);
    if (flag_status) {
      value->SetFlagStatus(flag_status.value());
      value->SetFlag(std::move(flag));
    } else {
      diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number())) << error);
      return false;
    }
  }

  if (value->GetFlagStatus() != FlagStatus::Disabled) {
    style->entries.push_back(Style::Entry{std::move(maybe_key.value()), std::move(value)});
  }
  return true;
}

+5 −0
Original line number Diff line number Diff line
@@ -302,6 +302,11 @@ message CompoundValue {
    Plural plural = 5;
    MacroBody macro = 6;
  }

  // The status of the flag the value is behind if any
  uint32 flag_status = 7;
  bool flag_negated = 8;
  string flag_name = 9;
}

// Message holding a boolean, so it can be optionally encoded.
+9 −10
Original line number Diff line number Diff line
@@ -551,11 +551,10 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr
          return false;
        }

        FeatureFlagAttribute flag;
        flag.name = pb_config_value.value().item().flag_name();
        flag.negated = pb_config_value.value().item().flag_negated();
        ResourceConfigValue* config_value =
            entry->FindOrCreateFlagDisabledValue(std::move(flag), config, pb_config.product());
        ResourceConfigValue* config_value = entry->FindOrCreateFlagDisabledValue(
            FeatureFlagAttribute{.name = pb_config_value.value().item().flag_name(),
                                 .negated = pb_config_value.value().item().flag_negated()},
            config, pb_config.product());
        if (config_value->value != nullptr) {
          *out_error = "duplicate configuration in resource table";
          return false;
@@ -563,7 +562,6 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr

        config_value->value = DeserializeValueFromPb(pb_config_value.value(), src_pool, config,
                                                     &out_table->string_pool, files, out_error);

        if (config_value->value == nullptr) {
          return false;
        }
@@ -896,6 +894,9 @@ std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value,
        LOG(FATAL) << "unknown compound value: " << (int)pb_compound_value.value_case();
        break;
    }
    value->SetFlagStatus((FlagStatus)pb_compound_value.flag_status());
    value->SetFlag(FeatureFlagAttribute{.name = pb_compound_value.flag_name(),
                                        .negated = pb_compound_value.flag_negated()});
  } else {
    LOG(FATAL) << "unknown value: " << (int)pb_value.value_case();
    return {};
@@ -1052,10 +1053,8 @@ std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item,
  if (item) {
    item->SetFlagStatus((FlagStatus)pb_item.flag_status());
    if (!pb_item.flag_name().empty()) {
      FeatureFlagAttribute flag;
      flag.name = pb_item.flag_name();
      flag.negated = pb_item.flag_negated();
      item->SetFlag(std::move(flag));
      item->SetFlag(
          FeatureFlagAttribute{.name = pb_item.flag_name(), .negated = pb_item.flag_negated()});
    }
  }
  return item;
+7 −0
Original line number Diff line number Diff line
@@ -734,6 +734,13 @@ void SerializeValueToPb(const Value& value, pb::Value* out_value, android::Strin
      out_value->mutable_item()->set_flag_negated(flag->negated);
      out_value->mutable_item()->set_flag_name(flag->name);
    }
  } else if (out_value->has_compound_value()) {
    out_value->mutable_compound_value()->set_flag_status((uint32_t)value.GetFlagStatus());
    if (value.GetFlag()) {
      const auto& flag = value.GetFlag();
      out_value->mutable_compound_value()->set_flag_negated(flag->negated);
      out_value->mutable_compound_value()->set_flag_name(flag->name);
    }
  }
}

Loading