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

Commit 4ab869e1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I2eef812b,I7b607192

* changes:
  AAPT v1 embed compile SDK version and codename into app
  AAPT2: Embed version of framework an app was compiled against.
parents b4de0609 11be9317
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ public:
          mSingleCrunchInputFile(NULL), mSingleCrunchOutputFile(NULL),
          mBuildSharedLibrary(false),
          mBuildAppAsSharedLibrary(false),
          mCompileSdkVersion(0),
          mArgc(0), mArgv(NULL)
        {}
    ~Bundle(void) {}
@@ -123,6 +124,10 @@ public:
    void setErrorOnFailedInsert(bool val) { mErrorOnFailedInsert = val; }
    bool getErrorOnMissingConfigEntry() { return mErrorOnMissingConfigEntry; }
    void setErrorOnMissingConfigEntry(bool val) { mErrorOnMissingConfigEntry = val; }
    const android::String8& getCompileSdkVersionCodename() { return mCompileSdkVersionCodename; }
    void setCompileSdkVersionCodename(const android::String8& codename) { mCompileSdkVersionCodename = codename; }
    int getCompileSdkVersion() { return mCompileSdkVersion; }
    void setCompileSdkVersion(int version) { mCompileSdkVersion = version; }
    const android::String8& getPlatformBuildVersionCode() { return mPlatformVersionCode; }
    void setPlatformBuildVersionCode(const android::String8& code) { mPlatformVersionCode = code; }
    const android::String8& getPlatformBuildVersionName() { return mPlatformVersionName; }
@@ -344,6 +349,8 @@ private:
    const char* mSingleCrunchOutputFile;
    bool        mBuildSharedLibrary;
    bool        mBuildAppAsSharedLibrary;
    int         mCompileSdkVersion;
    android::String8 mCompileSdkVersionCodename;
    android::String8 mPlatformVersionCode;
    android::String8 mPlatformVersionName;
    android::String8 mPrivateSymbolsPackage;
+32 −2
Original line number Diff line number Diff line
@@ -293,6 +293,8 @@ enum {
    ISGAME_ATTR = 0x10103f4,
    REQUIRED_FEATURE_ATTR = 0x1010557,
    REQUIRED_NOT_FEATURE_ATTR = 0x1010558,
    COMPILE_SDK_VERSION_ATTR = 0x01010572, // NOT FINALIZED
    COMPILE_SDK_VERSION_CODENAME_ATTR = 0x01010573, // NOT FINALIZED
};

String8 getComponentName(String8 &pkgName, String8 &componentName) {
@@ -1247,9 +1249,37 @@ int doDump(Bundle* bundle)
                                    splitName.string()).string());
                    }

                    String8 platformVersionName = AaptXml::getAttribute(tree, NULL,
                    String8 platformBuildVersionName = AaptXml::getAttribute(tree, NULL,
                            "platformBuildVersionName");
                    printf(" platformBuildVersionName='%s'", platformVersionName.string());
                    if (platformBuildVersionName != "") {
                        printf(" platformBuildVersionName='%s'", platformBuildVersionName.string());
                    }

                    String8 platformBuildVersionCode = AaptXml::getAttribute(tree, NULL,
                            "platformBuildVersionCode");
                    if (platformBuildVersionCode != "") {
                        printf(" platformBuildVersionCode='%s'", platformBuildVersionCode.string());
                    }

                    int32_t compileSdkVersion = AaptXml::getIntegerAttribute(tree,
                            COMPILE_SDK_VERSION_ATTR, &error);
                    if (error != "") {
                        SourcePos(manifestFile, tree.getLineNumber()).error(
                                "ERROR getting 'android:compileSdkVersion' attribute: %s",
                                error.string());
                        goto bail;
                    }
                    if (compileSdkVersion > 0) {
                        printf(" compileSdkVersion='%d'", compileSdkVersion);
                    }

                    String8 compileSdkVersionCodename = AaptXml::getResolvedAttribute(res, tree,
                            COMPILE_SDK_VERSION_CODENAME_ATTR, &error);
                    if (compileSdkVersionCodename != "") {
                        printf(" compileSdkVersionCodename='%s'", ResTable::normalizeForOutput(
                                compileSdkVersionCodename.string()).string());
                    }

                    printf("\n");

                    int32_t installLocation = AaptXml::getResolvedIntegerAttribute(res, tree,
+35 −3
Original line number Diff line number Diff line
@@ -918,6 +918,22 @@ status_t massageManifest(Bundle* bundle, ResourceTable* table, sp<XMLNode> root)
        }
    }


    if (bundle->getCompileSdkVersion() != 0) {
        if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "compileSdkVersion",
                    String8::format("%d", bundle->getCompileSdkVersion()),
                    errorOnFailedInsert, true)) {
            return UNKNOWN_ERROR;
        }
    }

    if (bundle->getCompileSdkVersionCodename() != "") {
        if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "compileSdkVersionCodename",
                    bundle->getCompileSdkVersionCodename(), errorOnFailedInsert, true)) {
            return UNKNOWN_ERROR;
        }
    }

    if (bundle->getPlatformBuildVersionCode() != "") {
        if (!addTagAttribute(root, "", "platformBuildVersionCode",
                    bundle->getPlatformBuildVersionCode(), errorOnFailedInsert, true)) {
@@ -1052,7 +1068,12 @@ enum {
    VERSION_NAME_ATTR = 0x0101021c,
};

static ssize_t extractPlatformBuildVersion(ResXMLTree& tree, Bundle* bundle) {
static ssize_t extractPlatformBuildVersion(const ResTable& table, ResXMLTree& tree, Bundle* bundle) {
    // First check if we should be recording the compileSdkVersion* attributes.
    static const String16 compileSdkVersionName("android:attr/compileSdkVersion");
    const bool useCompileSdkVersion = table.identifierForName(compileSdkVersionName.string(),
                                                              compileSdkVersionName.size()) != 0u;

    size_t len;
    ResXMLTree::event_code_t code;
    while ((code = tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
@@ -1082,6 +1103,10 @@ static ssize_t extractPlatformBuildVersion(ResXMLTree& tree, Bundle* bundle) {
            bundle->setPlatformBuildVersionCode(String8::format("%d", versionCode));
        }

        if (useCompileSdkVersion && versionCode >= 0 && bundle->getCompileSdkVersion() == 0) {
            bundle->setCompileSdkVersion(versionCode);
        }

        String8 versionName = AaptXml::getAttribute(tree, VERSION_NAME_ATTR, &error);
        if (error != "") {
            fprintf(stderr, "ERROR: failed to get platform version name\n");
@@ -1091,6 +1116,11 @@ static ssize_t extractPlatformBuildVersion(ResXMLTree& tree, Bundle* bundle) {
        if (versionName != "" && bundle->getPlatformBuildVersionName() == "") {
            bundle->setPlatformBuildVersionName(versionName);
        }

        if (useCompileSdkVersion && versionName != ""
                && bundle->getCompileSdkVersionCodename() == "") {
            bundle->setCompileSdkVersionCodename(versionName);
        }
        return NO_ERROR;
    }

@@ -1121,7 +1151,7 @@ static ssize_t extractPlatformBuildVersion(AssetManager& assets, Bundle* bundle)
            fprintf(stderr, "ERROR: Platform AndroidManifest.xml is corrupt\n");
            result = UNKNOWN_ERROR;
        } else {
            result = extractPlatformBuildVersion(tree, bundle);
            result = extractPlatformBuildVersion(assets.getResources(true), tree, bundle);
        }
    }

@@ -1707,7 +1737,9 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
    // extract them from the platform APK.
    if (packageType != ResourceTable::System &&
            (bundle->getPlatformBuildVersionCode() == "" ||
            bundle->getPlatformBuildVersionName() == "")) {
            bundle->getPlatformBuildVersionName() == "" ||
            bundle->getCompileSdkVersion() == 0 ||
            bundle->getCompileSdkVersionCodename() == "")) {
        err = extractPlatformBuildVersion(assets->getAssetManager(), bundle);
        if (err != NO_ERROR) {
            return UNKNOWN_ERROR;
+100 −4
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

#include <sys/stat.h>
#include <cinttypes>

#include <queue>
#include <unordered_map>
@@ -725,6 +726,30 @@ static bool LoadStableIdMap(IDiagnostics* diag, const std::string& path,
  return true;
}

static int32_t FindFrameworkAssetManagerCookie(const android::AssetManager& assets) {
  using namespace android;

  // Find the system package (0x01). AAPT always generates attributes with the type 0x01, so
  // we're looking for the first attribute resource in the system package.
  const ResTable& table = assets.getResources(true);
  Res_value val;
  ssize_t idx = table.getResource(0x01010000, &val, true);
  if (idx != NO_ERROR) {
    // Try as a bag.
    const ResTable::bag_entry* entry;
    ssize_t cnt = table.lockBag(0x01010000, &entry);
    if (cnt >= 0) {
      idx = entry->stringBlock;
    }
    table.unlockBag(entry);
  }

  if (idx < 0) {
    return 0;
  }
  return table.getTableCookie(idx);
}

class LinkCommand {
 public:
  LinkCommand(LinkContext* context, const LinkOptions& options)
@@ -734,7 +759,65 @@ class LinkCommand {
        file_collection_(util::make_unique<io::FileCollection>()) {
  }

  void ExtractCompileSdkVersions(android::AssetManager* assets) {
    using namespace android;

    int32_t cookie = FindFrameworkAssetManagerCookie(*assets);
    if (cookie == 0) {
      // No Framework assets loaded. Not a failure.
      return;
    }

    std::unique_ptr<Asset> manifest(
        assets->openNonAsset(cookie, kAndroidManifestPath, Asset::AccessMode::ACCESS_BUFFER));
    if (manifest == nullptr) {
      // No errors.
      return;
    }

    std::string error;
    std::unique_ptr<xml::XmlResource> manifest_xml =
        xml::Inflate(manifest->getBuffer(true /*wordAligned*/), manifest->getLength(), &error);
    if (manifest_xml == nullptr) {
      // No errors.
      return;
    }

    xml::Attribute* attr = manifest_xml->root->FindAttribute(xml::kSchemaAndroid, "versionCode");
    if (attr != nullptr) {
      Maybe<std::string>& compile_sdk_version = options_.manifest_fixer_options.compile_sdk_version;
      if (BinaryPrimitive* prim = ValueCast<BinaryPrimitive>(attr->compiled_value.get())) {
        switch (prim->value.dataType) {
          case Res_value::TYPE_INT_DEC:
            compile_sdk_version = StringPrintf("%" PRId32, static_cast<int32_t>(prim->value.data));
            break;
          case Res_value::TYPE_INT_HEX:
            compile_sdk_version = StringPrintf("%" PRIx32, prim->value.data);
            break;
          default:
            break;
        }
      } else if (String* str = ValueCast<String>(attr->compiled_value.get())) {
        compile_sdk_version = *str->value;
      } else {
        compile_sdk_version = attr->value;
      }
    }

    attr = manifest_xml->root->FindAttribute(xml::kSchemaAndroid, "versionName");
    if (attr != nullptr) {
      Maybe<std::string>& compile_sdk_version_codename =
          options_.manifest_fixer_options.compile_sdk_version_codename;
      if (String* str = ValueCast<String>(attr->compiled_value.get())) {
        compile_sdk_version_codename = *str->value;
      } else {
        compile_sdk_version_codename = attr->value;
      }
    }
  }

  // Creates a SymbolTable that loads symbols from the various APKs.
  // Pre-condition: context_->GetCompilationPackage() needs to be set.
  bool LoadSymbolsFromIncludePaths() {
    auto asset_source = util::make_unique<AssetManagerSymbolSource>();
    for (const std::string& path : options_.include_paths) {
@@ -802,6 +885,17 @@ class LinkCommand {
      } else if (entry.first == kAppPackageId) {
        // Capture the included base feature package.
        included_feature_base_ = entry.second;
      } else if (entry.first == kFrameworkPackageId) {
        // Try to embed which version of the framework we're compiling against.
        // First check if we should use compileSdkVersion at all. Otherwise compilation may fail
        // when linking our synthesized 'android:compileSdkVersion' attribute.
        std::unique_ptr<SymbolTable::Symbol> symbol = asset_source->FindByName(
            ResourceName("android", ResourceType::kAttr, "compileSdkVersion"));
        if (symbol != nullptr && symbol->is_public) {
          // The symbol is present and public, extract the android:versionName and
          // android:versionCode from the framework AndroidManifest.xml.
          ExtractCompileSdkVersions(asset_source->GetAssetManager());
        }
      }
    }

@@ -1535,6 +1629,12 @@ class LinkCommand {
      context_->SetCompilationPackage(app_info.package);
    }

    // Now that the compilation package is set, load the dependencies. This will also extract
    // the Android framework's versionCode and versionName, if they exist.
    if (!LoadSymbolsFromIncludePaths()) {
      return 1;
    }

    ManifestFixer manifest_fixer(options_.manifest_fixer_options);
    if (!manifest_fixer.Consume(context_, manifest_xml.get())) {
      return 1;
@@ -1563,10 +1663,6 @@ class LinkCommand {
      }
    }

    if (!LoadSymbolsFromIncludePaths()) {
      return 1;
    }

    TableMergerOptions table_merger_options;
    table_merger_options.auto_add_overlay = options_.auto_add_overlay;
    table_merger_ = util::make_unique<TableMerger>(context_, &final_table_, table_merger_options);
+19 −0
Original line number Diff line number Diff line
@@ -406,6 +406,25 @@ bool ManifestFixer::Consume(IAaptContext* context, xml::XmlResource* doc) {
    root->InsertChild(0, std::move(uses_sdk));
  }

  if (options_.compile_sdk_version) {
    xml::Attribute* attr = root->FindOrCreateAttribute(xml::kSchemaAndroid, "compileSdkVersion");

    // Make sure we un-compile the value if it was set to something else.
    attr->compiled_value = {};

    attr->value = options_.compile_sdk_version.value();
  }

  if (options_.compile_sdk_version_codename) {
    xml::Attribute* attr =
        root->FindOrCreateAttribute(xml::kSchemaAndroid, "compileSdkVersionCodename");

    // Make sure we un-compile the value if it was set to something else.
    attr->compiled_value = {};

    attr->value = options_.compile_sdk_version_codename.value();
  }

  xml::XmlActionExecutor executor;
  if (!BuildRules(&executor, context->GetDiagnostics())) {
    return false;
Loading