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

Commit 0c6ff1da authored by Mårten Kongstad's avatar Mårten Kongstad Committed by Todd Kennedy
Browse files

idmap2: move commands to Result<Unit>

Change the signature of the idmap2 commands (Create, Dump, ...) to
return Result<Unit> instead of bool. This removes the need to pass in an
ostream for error messages: instead, those messages are part of the
returned Result.

Consolidate error messages: texts in Error objects should not be
prefixed with "error:", that is the responsibility of the outer-most
caller (i.e. main()).

Test: make idmap2_tests
Change-Id: I074881b3d1982ea8f4be5752161ac74b14fcba95
parent 09eb96c4
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -20,10 +20,12 @@
#include <string>
#include <vector>

bool Create(const std::vector<std::string>& args, std::ostream& out_error);
bool Dump(const std::vector<std::string>& args, std::ostream& out_error);
bool Lookup(const std::vector<std::string>& args, std::ostream& out_error);
bool Scan(const std::vector<std::string>& args, std::ostream& out_error);
bool Verify(const std::vector<std::string>& args, std::ostream& out_error);
#include "idmap2/Result.h"

android::idmap2::Result<android::idmap2::Unit> Create(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> Dump(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> Lookup(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> Scan(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> Verify(const std::vector<std::string>& args);

#endif  // IDMAP2_IDMAP2_COMMANDS_H_
+17 −19
Original line number Diff line number Diff line
@@ -33,14 +33,17 @@
using android::ApkAssets;
using android::idmap2::BinaryStreamVisitor;
using android::idmap2::CommandLineOptions;
using android::idmap2::Error;
using android::idmap2::Idmap;
using android::idmap2::PoliciesToBitmask;
using android::idmap2::PolicyBitmask;
using android::idmap2::PolicyFlags;
using android::idmap2::Result;
using android::idmap2::Unit;
using android::idmap2::utils::kIdmapFilePermissionMask;
using android::idmap2::utils::UidHasWriteAccessToPath;

bool Create(const std::vector<std::string>& args, std::ostream& out_error) {
Result<Unit> Create(const std::vector<std::string>& args) {
  SYSTRACE << "Create " << args;
  std::string target_apk_path;
  std::string overlay_apk_path;
@@ -63,15 +66,14 @@ bool Create(const std::vector<std::string>& args, std::ostream& out_error) {
                          &policies)
          .OptionalFlag("--ignore-overlayable", "disables overlayable and policy checks",
                        &ignore_overlayable);
  if (!opts.Parse(args, out_error)) {
    return false;
  const auto opts_ok = opts.Parse(args);
  if (!opts_ok) {
    return opts_ok.GetError();
  }

  const uid_t uid = getuid();
  if (!UidHasWriteAccessToPath(uid, idmap_path)) {
    out_error << "error: uid " << uid << " does not have write access to " << idmap_path
              << std::endl;
    return false;
    return Error("uid %d does not have write access to %s", uid, idmap_path.c_str());
  }

  PolicyBitmask fulfilled_policies = 0;
@@ -79,8 +81,7 @@ bool Create(const std::vector<std::string>& args, std::ostream& out_error) {
  if (conv_result) {
    fulfilled_policies |= *conv_result;
  } else {
    out_error << "error: " << conv_result.GetErrorMessage() << std::endl;
    return false;
    return conv_result.GetError();
  }

  if (fulfilled_policies == 0) {
@@ -89,36 +90,33 @@ bool Create(const std::vector<std::string>& args, std::ostream& out_error) {

  const std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
  if (!target_apk) {
    out_error << "error: failed to load apk " << target_apk_path << std::endl;
    return false;
    return Error("failed to load apk %s", target_apk_path.c_str());
  }

  const std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
  if (!overlay_apk) {
    out_error << "error: failed to load apk " << overlay_apk_path << std::endl;
    return false;
    return Error("failed to load apk %s", overlay_apk_path.c_str());
  }

  std::stringstream stream;
  const std::unique_ptr<const Idmap> idmap =
      Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
                           fulfilled_policies, !ignore_overlayable, out_error);
                           fulfilled_policies, !ignore_overlayable, stream);
  if (!idmap) {
    return false;
    return Error("failed to create idmap: %s", stream.str().c_str());
  }

  umask(kIdmapFilePermissionMask);
  std::ofstream fout(idmap_path);
  if (fout.fail()) {
    out_error << "failed to open idmap path " << idmap_path << std::endl;
    return false;
    return Error("failed to open idmap path %s", idmap_path.c_str());
  }
  BinaryStreamVisitor visitor(fout);
  idmap->accept(&visitor);
  fout.close();
  if (fout.fail()) {
    out_error << "failed to write to idmap path " << idmap_path << std::endl;
    return false;
    return Error("failed to write to idmap path %s", idmap_path.c_str());
  }

  return true;
  return Unit{};
}
+13 −6
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <fstream>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

@@ -24,14 +25,18 @@
#include "idmap2/Idmap.h"
#include "idmap2/PrettyPrintVisitor.h"
#include "idmap2/RawPrintVisitor.h"
#include "idmap2/Result.h"
#include "idmap2/SysTrace.h"

using android::idmap2::CommandLineOptions;
using android::idmap2::Error;
using android::idmap2::Idmap;
using android::idmap2::PrettyPrintVisitor;
using android::idmap2::RawPrintVisitor;
using android::idmap2::Result;
using android::idmap2::Unit;

bool Dump(const std::vector<std::string>& args, std::ostream& out_error) {
Result<Unit> Dump(const std::vector<std::string>& args) {
  SYSTRACE << "Dump " << args;
  std::string idmap_path;
  bool verbose;
@@ -40,14 +45,16 @@ bool Dump(const std::vector<std::string>& args, std::ostream& out_error) {
      CommandLineOptions("idmap2 dump")
          .MandatoryOption("--idmap-path", "input: path to idmap file to pretty-print", &idmap_path)
          .OptionalFlag("--verbose", "annotate every byte of the idmap", &verbose);
  if (!opts.Parse(args, out_error)) {
    return false;
  const auto opts_ok = opts.Parse(args);
  if (!opts_ok) {
    return opts_ok.GetError();
  }
  std::stringstream stream;
  std::ifstream fin(idmap_path);
  const std::unique_ptr<const Idmap> idmap = Idmap::FromBinaryStream(fin, out_error);
  const std::unique_ptr<const Idmap> idmap = Idmap::FromBinaryStream(fin, stream);
  fin.close();
  if (!idmap) {
    return false;
    return Error("failed to load idmap: %s", stream.str().c_str());
  }

  if (verbose) {
@@ -58,5 +65,5 @@ bool Dump(const std::vector<std::string>& args, std::ostream& out_error) {
    idmap->accept(&visitor);
  }

  return true;
  return Unit{};
}
+17 −24
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ using android::idmap2::Error;
using android::idmap2::IdmapHeader;
using android::idmap2::ResourceId;
using android::idmap2::Result;
using android::idmap2::Unit;
using android::idmap2::Xml;
using android::idmap2::ZipFile;
using android::util::Utf16ToUtf8;
@@ -157,7 +158,7 @@ Result<std::string> GetTargetPackageNameFromManifest(const std::string& apk_path
}
}  // namespace

bool Lookup(const std::vector<std::string>& args, std::ostream& out_error) {
Result<Unit> Lookup(const std::vector<std::string>& args) {
  SYSTRACE << "Lookup " << args;
  std::vector<std::string> idmap_paths;
  std::string config_str;
@@ -172,14 +173,14 @@ bool Lookup(const std::vector<std::string>& args, std::ostream& out_error) {
                           "'[package:]type/name') to look up",
                           &resid_str);

  if (!opts.Parse(args, out_error)) {
    return false;
  const auto opts_ok = opts.Parse(args);
  if (!opts_ok) {
    return opts_ok.GetError();
  }

  ConfigDescription config;
  if (!ConfigDescription::Parse(config_str, &config)) {
    out_error << "error: failed to parse config" << std::endl;
    return false;
    return Error("failed to parse config");
  }

  std::vector<std::unique_ptr<const ApkAssets>> apk_assets;
@@ -191,39 +192,33 @@ bool Lookup(const std::vector<std::string>& args, std::ostream& out_error) {
    auto idmap_header = IdmapHeader::FromBinaryStream(fin);
    fin.close();
    if (!idmap_header) {
      out_error << "error: failed to read idmap from " << idmap_path << std::endl;
      return false;
      return Error("failed to read idmap from %s", idmap_path.c_str());
    }

    if (i == 0) {
      target_path = idmap_header->GetTargetPath().to_string();
      auto target_apk = ApkAssets::Load(target_path);
      if (!target_apk) {
        out_error << "error: failed to read target apk from " << target_path << std::endl;
        return false;
        return Error("failed to read target apk from %s", target_path.c_str());
      }
      apk_assets.push_back(std::move(target_apk));

      const Result<std::string> package_name =
          GetTargetPackageNameFromManifest(idmap_header->GetOverlayPath().to_string());
      if (!package_name) {
        out_error << "error: failed to parse android:targetPackage from overlay manifest"
                  << std::endl;
        return false;
        return Error("failed to parse android:targetPackage from overlay manifest");
      }
      target_package_name = *package_name;
    } else if (target_path != idmap_header->GetTargetPath()) {
      out_error << "error: different target APKs (expected target APK " << target_path << " but "
                << idmap_path << " has target APK " << idmap_header->GetTargetPath() << ")"
                << std::endl;
      return false;
      return Error("different target APKs (expected target APK %s but %s has target APK %s)",
                   target_path.c_str(), idmap_path.c_str(),
                   idmap_header->GetTargetPath().to_string().c_str());
    }

    auto overlay_apk = ApkAssets::LoadOverlay(idmap_path);
    if (!overlay_apk) {
      out_error << "error: failed to read overlay apk from " << idmap_header->GetOverlayPath()
                << std::endl;
      return false;
      return Error("failed to read overlay apk from %s",
                   idmap_header->GetOverlayPath().to_string().c_str());
    }
    apk_assets.push_back(std::move(overlay_apk));
  }
@@ -238,16 +233,14 @@ bool Lookup(const std::vector<std::string>& args, std::ostream& out_error) {

  const Result<ResourceId> resid = ParseResReference(am, resid_str, target_package_name);
  if (!resid) {
    out_error << "error: failed to parse resource ID" << std::endl;
    return false;
    return Error(resid.GetError(), "failed to parse resource ID");
  }

  const Result<std::string> value = GetValue(am, *resid);
  if (!value) {
    out_error << StringPrintf("error: resource 0x%08x not found", *resid) << std::endl;
    return false;
    return Error(value.GetError(), "resource 0x%08x not found", *resid);
  }
  std::cout << *value << std::endl;

  return true;
  return Unit{};
}
+10 −2
Original line number Diff line number Diff line
@@ -24,14 +24,17 @@
#include <vector>

#include "idmap2/CommandLineOptions.h"
#include "idmap2/Result.h"
#include "idmap2/SysTrace.h"

#include "Commands.h"

using android::idmap2::CommandLineOptions;
using android::idmap2::Result;
using android::idmap2::Unit;

using NameToFunctionMap =
    std::map<std::string, std::function<bool(const std::vector<std::string>&, std::ostream&)>>;
    std::map<std::string, std::function<Result<Unit>(const std::vector<std::string>&)>>;

namespace {

@@ -69,5 +72,10 @@ int main(int argc, char** argv) {
    PrintUsage(commands, std::cerr);
    return EXIT_FAILURE;
  }
  return iter->second(*args, std::cerr) ? EXIT_SUCCESS : EXIT_FAILURE;
  const auto result = iter->second(*args);
  if (!result) {
    std::cerr << "error: " << result.GetErrorMessage() << std::endl;
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}
Loading