class DeviceAPI::Android::Signing

Namespace for all methods encapsulating adb calls

Public Class Methods

generate_keystore(options = {}) click to toggle source

Creates a keystore used for signing apks @param [Hash] options options to pass through to keytool @option options [String] :keystore ('~/.android/debug.keystore') full path to location to create keystore @option options [String] :alias ('androiddebugkey') keystore alias name @option options [String] :dname ('CN=hive') keystore dname @option options [String] :password ('android') keystore password @return [Boolean, Exception] returns true if a keystore is created, otherwise an exception is raised

# File lib/device_api/android/signing.rb, line 15
def self.generate_keystore(options = {})
  keystore    = options[:keystore]  || '~/.android/debug.keystore'
  alias_name  = options[:alias]     || 'androiddebugkey'
  dname       = options[:dname]     || 'CN=hive'
  password    = options[:password]  || 'android'

  result = execute("keytool -genkey -noprompt -alias #{alias_name} -dname '#{dname}' -keystore #{keystore} -storepass #{password} -keypass #{password} -keyalg RSA -keysize 2048 -validity 10000")
  raise SigningCommandError.new(result.stderr) if result.exit != 0
  true
end
is_apk_signed?(apk_path) click to toggle source

Checks to see if an apk has already been signed @param [String] apk_path full path to apk to check @return returns false if the apk is unsigned, true if it is signed

# File lib/device_api/android/signing.rb, line 56
def self.is_apk_signed?(apk_path)
  raise SigningCommandError.new('AAPT not available') unless DeviceAPI::Android::AAPT.aapt_available?
  result = execute("aapt list #{apk_path} | grep '^META-INF\/.*'")
  return false if result.stdout.empty?
  true
end
sign_apk(options = {}) click to toggle source

Signs an apk using the specified keystore @param [Hash] options options to pass through to jarsigner @option options [String] :apk full path to the apk to sign @option options [String] :alias ('androiddebugkey') alias of the keystore @option options [String] :keystore ('~/.android/debug.keystore') full path to the location of the keystore @option options [String] :keystore_password ('android') password required to open the keystore @option options [Boolean] :resign if true then an already signed apk will be stripped of previous signing and resigned @return [Boolean, Exception] return true if the apk is signed, false if the apk is already signed and resigning is anything other than true

otherwise an exception is raised
# File lib/device_api/android/signing.rb, line 35
def self.sign_apk(options = {})
  apk               = options[:apk]
  alias_name        = options[:alias]             || 'androiddebugkey'
  keystore          = options[:keystore]          || '~/.android/debug.keystore'
  keystore_password = options[:keystore_password] || 'android'
  resign            = options[:resign]

  # Check to see if the APK has already been signed
  if is_apk_signed?(apk)
    return false unless resign
    unsign_apk(apk)
  end
  generate_keystore({ keystore: keystore, password: keystore_password, alias_name: alias_name }) unless File.exists?(File.expand_path(keystore))
  result = execute("jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore #{File.expand_path(keystore)} -storepass #{keystore_password} #{apk} #{alias_name}")
  raise SigningCommandError.new(result.stderr) if result.exit != 0
  true
end
unsign_apk(apk_path) click to toggle source

Removes any previous signatures from an apk @param [String] apk_path full path to the apk @return [Boolean, Exception] returns true if the apk is successfully unsigned, otherwise an exception is raised

# File lib/device_api/android/signing.rb, line 66
def self.unsign_apk(apk_path)
  raise SigningCommandError.new('AAPT not available') unless DeviceAPI::Android::AAPT.aapt_available?
  file_list = execute("aapt list #{apk_path} | grep '^META-INF\/.*'")
  result = execute("aapt remove #{apk_path} #{file_list.stdout.split(/\s+/).join(' ')}")
  raise SigningCommandError.new(result.stderr) if result.exit != 0
  true
 end