class Apkstats::Command::ApkAnalyzer

Public Class Methods

new(opts) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 7
def initialize(opts)
  @command_path = opts.fetch(:command_path)
end
parse_features(command_output) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 61
def self.parse_features(command_output)
  command_output.split(/\r?\n/).map { |s| to_feature(s) }
end
parse_permissions(command_output) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 51
def self.parse_permissions(command_output)
  command_output.split(/\r?\n/).map { |s| to_permission(s) }
end
parse_reference_to_map(command_output) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 73
def self.parse_reference_to_map(command_output)
  command_output.split(/\r?\n/).each_with_object({}) do |s, acc|
    dex_file, method_count = s.strip.split(/\t/, 2)
    acc[dex_file] = method_count
  end
end
to_feature(str) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 65
def self.to_feature(str)
  # format / name implied: xxxx
  # not-required and implied cannot co-exist so it's okay to parse them like this
  name, kind, tail = str.strip.split(/\s/, 3)

  ::Apkstats::Entity::Feature.new(name, not_required: kind == "not-required", implied_reason: kind == "implied:" && tail)
end
to_permission(str) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 55
def self.to_permission(str)
  # If maxSdkVersion is specified, the output is like `android.permission.INTERNET' maxSdkVersion='23`
  name_seed, max_sdk_seed = str.strip.split(/\s/)
  ::Apkstats::Entity::Permission.new(name_seed.gsub(/'$/, ""), max_sdk: max_sdk_seed && max_sdk_seed[/[0-9]+/])
end

Public Instance Methods

dex_count(apk_filepath) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 47
def dex_count(apk_filepath)
  ApkAnalyzer.parse_reference_to_map(run_command("dex", "references", apk_filepath)).size
end
download_size(apk_filepath) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 15
def download_size(apk_filepath)
  run_command("apk", "download-size", apk_filepath)
end
file_size(apk_filepath) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 11
def file_size(apk_filepath)
  run_command("apk", "file-size", apk_filepath)
end
method_reference_count(apk_filepath) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 40
def method_reference_count(apk_filepath)
  ApkAnalyzer.parse_reference_to_map(run_command("dex", "references", apk_filepath))
    .values
    .map(&:to_i)
    .inject(:+)
end
min_sdk(apk_filepath) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 32
def min_sdk(apk_filepath)
  run_command("manifest", "min-sdk", apk_filepath)
end
non_required_features(apk_filepath) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 23
def non_required_features(apk_filepath)
  all_features = ApkAnalyzer.parse_features(run_command("apk", "features", "--not-required", apk_filepath))
  Apkstats::Entity::Features.new(all_features.select(&:not_required?))
end
permissions(apk_filepath) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 28
def permissions(apk_filepath)
  ::Apkstats::Entity::Permissions.new(ApkAnalyzer.parse_permissions(run_command("manifest", "permissions", apk_filepath)))
end
required_features(apk_filepath) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 19
def required_features(apk_filepath)
  ::Apkstats::Entity::Features.new(ApkAnalyzer.parse_features(run_command("apk", "features", apk_filepath)))
end
target_sdk(apk_filepath) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 36
def target_sdk(apk_filepath)
  run_command("manifest", "target-sdk", apk_filepath)
end

Private Instance Methods

run_command(*args) click to toggle source
# File lib/apkstats/command/apk_analyzer.rb, line 82
def run_command(*args)
  out, err, status = Open3.capture3(command_path, *args)
  raise err unless status.success?

  out.rstrip
end