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

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

Merge "AAPT2: Set the minSdkVersion when generating multiple APKs."

parents e7a3add8 3edd4726
Loading
Loading
Loading
Loading
+42 −1
Original line number Diff line number Diff line
@@ -20,11 +20,15 @@
#include "ValueVisitor.h"
#include "flatten/Archive.h"
#include "flatten/TableFlattener.h"
#include "flatten/XmlFlattener.h"
#include "io/BigBufferInputStream.h"
#include "io/Util.h"
#include "xml/XmlDom.h"

namespace aapt {

using xml::XmlResource;

std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(IAaptContext* context,
                                                      const android::StringPiece& path) {
  Source source(path);
@@ -52,6 +56,7 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(IAaptContext* context,
  if (!parser.Parse()) {
    return {};
  }

  return util::make_unique<LoadedApk>(source, std::move(apk), std::move(table));
}

@@ -63,7 +68,7 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, const TableFlattenerOption

bool LoadedApk::WriteToArchive(IAaptContext* context, ResourceTable* split_table,
                               const TableFlattenerOptions& options, FilterChain* filters,
                               IArchiveWriter* writer) {
                               IArchiveWriter* writer, XmlResource* manifest) {
  std::set<std::string> referenced_resources;
  // List the files being referenced in the resource table.
  for (auto& pkg : split_table->packages) {
@@ -119,6 +124,20 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, ResourceTable* split_table
        return false;
      }

    } else if (manifest != nullptr && path == "AndroidManifest.xml") {
      BigBuffer buffer(8192);
      XmlFlattener xml_flattener(&buffer, {});
      if (!xml_flattener.Consume(context, manifest)) {
        context->GetDiagnostics()->Error(DiagMessage(path) << "flattening failed");
        return false;
      }

      uint32_t compression_flags = file->WasCompressed() ? ArchiveEntry::kCompress : 0u;
      io::BigBufferInputStream manifest_buffer_in(&buffer);
      if (!io::CopyInputStreamToArchive(context, &manifest_buffer_in, path, compression_flags,
                                        writer)) {
        return false;
      }
    } else {
      uint32_t compression_flags = file->WasCompressed() ? ArchiveEntry::kCompress : 0u;
      if (!io::CopyFileToArchive(context, file, path, compression_flags, writer)) {
@@ -129,4 +148,26 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, ResourceTable* split_table
  return true;
}

std::unique_ptr<xml::XmlResource> LoadedApk::InflateManifest(IAaptContext* context) {
  IDiagnostics* diag = context->GetDiagnostics();

  io::IFile* manifest_file = GetFileCollection()->FindFile("AndroidManifest.xml");
  if (manifest_file == nullptr) {
    diag->Error(DiagMessage(source_) << "no AndroidManifest.xml found");
    return {};
  }

  std::unique_ptr<io::IData> manifest_data = manifest_file->OpenAsData();
  if (manifest_data == nullptr) {
    diag->Error(DiagMessage(manifest_file->GetSource()) << "could not open AndroidManifest.xml");
    return {};
  }

  std::unique_ptr<xml::XmlResource> manifest =
      xml::Inflate(manifest_data->data(), manifest_data->size(), diag, manifest_file->GetSource());
  if (manifest == nullptr) {
    diag->Error(DiagMessage() << "failed to read binary AndroidManifest.xml");
  }
  return manifest;
}
}  // namespace aapt
+16 −9
Original line number Diff line number Diff line
@@ -25,17 +25,17 @@
#include "flatten/TableFlattener.h"
#include "io/ZipArchive.h"
#include "unflatten/BinaryResourceParser.h"
#include "xml/XmlDom.h"

namespace aapt {

/** Info about an APK loaded in memory. */
class LoadedApk {
 public:
  LoadedApk(
      const Source& source,
      std::unique_ptr<io::IFileCollection> apk,
  LoadedApk(const Source& source, std::unique_ptr<io::IFileCollection> apk,
            std::unique_ptr<ResourceTable> table)
      : source_(source), apk_(std::move(apk)), table_(std::move(table)) {}
      : source_(source), apk_(std::move(apk)), table_(std::move(table)) {
  }

  io::IFileCollection* GetFileCollection() { return apk_.get(); }

@@ -51,13 +51,20 @@ class LoadedApk {
                              IArchiveWriter* writer);

  /**
   * Writes the APK on disk at the given path, while also removing the resource
   * files that are not referenced in the resource table. The provided filter
   * chain is applied to each entry in the APK file.
   * Writes the APK on disk at the given path, while also removing the resource files that are not
   * referenced in the resource table. The provided filter chain is applied to each entry in the APK
   * file.
   *
   * If the manifest is also provided, it will be written to the new APK file, otherwise the
   * original manifest will be written. The manifest is only required if the contents of the new APK
   * have been modified in a way that require the AndroidManifest.xml to also be modified.
   */
  virtual bool WriteToArchive(IAaptContext* context, ResourceTable* split_table,
                              const TableFlattenerOptions& options, FilterChain* filters,
                              IArchiveWriter* writer);
                              IArchiveWriter* writer, xml::XmlResource* manifest = nullptr);

  /** Inflates the AndroidManifest.xml file from the APK. */
  std::unique_ptr<xml::XmlResource> InflateManifest(IAaptContext* context);

  static std::unique_ptr<LoadedApk> LoadApkFromPath(IAaptContext* context,
                                                    const android::StringPiece& path);
+1 −17
Original line number Diff line number Diff line
@@ -283,24 +283,8 @@ class OptimizeCommand {

bool ExtractAppDataFromManifest(OptimizeContext* context, LoadedApk* apk,
                                OptimizeOptions* out_options) {
  io::IFile* manifest_file = apk->GetFileCollection()->FindFile("AndroidManifest.xml");
  if (manifest_file == nullptr) {
    context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
                                     << "missing AndroidManifest.xml");
    return false;
  }

  std::unique_ptr<io::IData> data = manifest_file->OpenAsData();
  if (data == nullptr) {
    context->GetDiagnostics()->Error(DiagMessage(manifest_file->GetSource())
                                     << "failed to open file");
    return false;
  }

  std::unique_ptr<xml::XmlResource> manifest = xml::Inflate(
      data->data(), data->size(), context->GetDiagnostics(), manifest_file->GetSource());
  std::unique_ptr<xml::XmlResource> manifest = apk->InflateManifest(context);
  if (manifest == nullptr) {
    context->GetDiagnostics()->Error(DiagMessage() << "failed to read binary AndroidManifest.xml");
    return false;
  }

+4 −3
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include "ConfigDescription.h"
#include "Diagnostics.h"
#include "ResourceUtils.h"
#include "io/File.h"
#include "io/FileSystem.h"
#include "io/StringInputStream.h"
@@ -499,11 +500,11 @@ ConfigurationParser::ActionHandler ConfigurationParser::android_sdk_group_handle
      AndroidSdk entry;
      for (const auto& attr : child->attributes) {
        if (attr.name == "minSdkVersion") {
          entry.min_sdk_version = {attr.value};
          entry.min_sdk_version = ResourceUtils::ParseSdkVersion(attr.value);
        } else if (attr.name == "targetSdkVersion") {
          entry.target_sdk_version = {attr.value};
          entry.target_sdk_version = ResourceUtils::ParseSdkVersion(attr.value);
        } else if (attr.name == "maxSdkVersion") {
          entry.max_sdk_version = {attr.value};
          entry.max_sdk_version = ResourceUtils::ParseSdkVersion(attr.value);
        } else {
          diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name << " = " << attr.value);
        }
+5 −5
Original line number Diff line number Diff line
@@ -103,14 +103,14 @@ struct AndroidManifest {
};

struct AndroidSdk {
  Maybe<std::string> min_sdk_version;
  Maybe<std::string> target_sdk_version;
  Maybe<std::string> max_sdk_version;
  Maybe<int> min_sdk_version;
  Maybe<int> target_sdk_version;
  Maybe<int> max_sdk_version;
  Maybe<AndroidManifest> manifest;

  static AndroidSdk ForMinSdk(std::string min_sdk) {
  static AndroidSdk ForMinSdk(int min_sdk) {
    AndroidSdk sdk;
    sdk.min_sdk_version = {std::move(min_sdk)};
    sdk.min_sdk_version = min_sdk;
    return sdk;
  }

Loading