Class: Flick::Android

Inherits:
Object
  • Object
show all
Defined in:
lib/flick/android.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Android

Returns a new instance of Android.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/flick/android.rb', line 5

def initialize options
  Flick::Checker.system_dependency "adb"
  if options[:udid].nil?
    self.udid = get_device_udid
  else
    self.udid = options[:udid]
  end
  self.flick_dir = "#{Dir.home}/.flick/#{udid}"
  self.dir_name = "sdcard/flick"
  self.name = remove_bad_characters(options.fetch(:name, self.udid))
  self.outdir = options.fetch(:outdir, Dir.pwd)
  self.unique = options.fetch(:unique, true).to_b
  self.limit = options.fetch(:limit, 180)
  self.specs = options.fetch(:specs, false)
  self.size = options.fetch(:size, "720x1280")
  create_flick_dirs
end

Instance Attribute Details

#dir_nameObject

Returns the value of attribute dir_name.



3
4
5
# File 'lib/flick/android.rb', line 3

def dir_name
  @dir_name
end

#flick_dirObject

Returns the value of attribute flick_dir.



3
4
5
# File 'lib/flick/android.rb', line 3

def flick_dir
  @flick_dir
end

#limitObject

Returns the value of attribute limit.



3
4
5
# File 'lib/flick/android.rb', line 3

def limit
  @limit
end

#nameObject

Returns the value of attribute name.



3
4
5
# File 'lib/flick/android.rb', line 3

def name
  @name
end

#outdirObject

Returns the value of attribute outdir.



3
4
5
# File 'lib/flick/android.rb', line 3

def outdir
  @outdir
end

#sizeObject

Returns the value of attribute size.



3
4
5
# File 'lib/flick/android.rb', line 3

def size
  @size
end

#specsObject

Returns the value of attribute specs.



3
4
5
# File 'lib/flick/android.rb', line 3

def specs
  @specs
end

#udidObject

Returns the value of attribute udid.



3
4
5
# File 'lib/flick/android.rb', line 3

def udid
  @udid
end

#uniqueObject

Returns the value of attribute unique.



3
4
5
# File 'lib/flick/android.rb', line 3

def unique
  @unique
end

Instance Method Details

#app_installed?(package) ⇒ Boolean

Returns:

  • (Boolean)


133
134
135
# File 'lib/flick/android.rb', line 133

def app_installed? package
  packages.include? "package:#{package}"
end

#app_version(app_path) ⇒ Object



119
120
121
# File 'lib/flick/android.rb', line 119

def app_version app_path
  manifest(app_path).find {|x| x.name == "versionName" }["value"]
end

#check_for_devicesObject



50
51
52
53
54
55
# File 'lib/flick/android.rb', line 50

def check_for_devices
  unless devices_connected?
    puts "\nNo Devices Connected or Authorized!!!\nMake sure at least one device (emulator/simulator) is connected!\n".red
    abort
  end
end

#clear_filesObject



37
38
39
40
# File 'lib/flick/android.rb', line 37

def clear_files
  Flick::System.clean_system_dir flick_dir, udid
  %x(adb -s #{udid} shell rm '#{dir_name}/*')
end

#cpu(package) ⇒ Object



90
91
92
# File 'lib/flick/android.rb', line 90

def cpu package
  %x(adb -s #{udid} shell top -n 1 -d 1 | grep #{package} | awk '{print $3}').strip.chomp("%").to_i
end

#create_flick_dirsObject



27
28
29
30
31
32
33
34
35
# File 'lib/flick/android.rb', line 27

def create_flick_dirs
  Flick::System.setup_system_dir "#{Dir.home}/.flick"
  Flick::System.setup_system_dir flick_dir
  message = %x(adb -s #{udid} shell 'mkdir #{dir_name}').split(":").last.strip rescue nil
  if message == "Read-only file system"
    puts "\nDevice: '#{udid}' is a 'Read-only file system'! Flick cannot write to the sdcard folder. Aborting...\n".red
    abort
  end
end

#devicesObject



42
43
44
# File 'lib/flick/android.rb', line 42

def devices
  (`adb devices`).scan(/\n(.*)\t/).flatten
end

#devices_connected?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/flick/android.rb', line 46

def devices_connected?
  devices.any?
end

#get_device_udidObject



57
58
59
60
61
62
63
64
65
# File 'lib/flick/android.rb', line 57

def get_device_udid
  check_for_devices
  if devices.size == 1
    devices.first
  else
    puts "\nMultiple android devices '#{devices}' found.\nSpecify a single UDID. e.g. -u #{devices.sample}\n".red
    abort unless specs
  end
end

#get_vitals(package) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
# File 'lib/flick/android.rb', line 94

def get_vitals package
  if app_installed? package
    stats = JSON.generate({ app_stats: { memory_mb: memory(package), cpu_per: cpu(package) }, system_stats: system_stats })
    json = JSON.parse stats
    puts json
    json
  else
    puts packages
    puts "\n#{package} was not found on device #{udid}! Please choose one from above. e.g. #{packages.sample}\n".red
  end
end

#infoObject



67
68
69
70
71
72
73
74
75
# File 'lib/flick/android.rb', line 67

def info
  specs = { os: "ro.build.version.release", manufacturer: "ro.product.manufacturer", model: "ro.product.model", sdk: "ro.build.version.sdk" }
  hash = { udid: udid }
  specs.each do |key, spec|
    value = `adb -s #{udid} shell getprop "#{spec}"`.strip
    hash.merge!({key=> "#{value}"})
  end
  hash
end

#install(app_path) ⇒ Object



106
107
108
# File 'lib/flick/android.rb', line 106

def install app_path
  %x(adb -s #{udid} install -r #{app_path})
end

#log(name) ⇒ Object



149
150
151
152
# File 'lib/flick/android.rb', line 149

def log name
  %x(adb -s #{udid} logcat -c)
  %x(adb -s #{udid} logcat -v long > #{outdir}/#{name}.log)
end

#manifest(app_path) ⇒ Object



127
128
129
130
131
# File 'lib/flick/android.rb', line 127

def manifest app_path
  data = ApkXml.new app_path
  data.parse_xml("AndroidManifest.xml", false, true)
  data.xml_elements[0].attributes
end

#memory(package) ⇒ Object



86
87
88
# File 'lib/flick/android.rb', line 86

def memory package
  (%x(adb -s #{udid} shell dumpsys meminfo | grep #{package} | awk '{print $1}').strip.split.last.to_i * 0.001).round(2)
end

#os_versionObject



141
142
143
# File 'lib/flick/android.rb', line 141

def os_version
  %x(adb -s #{udid} shell getprop "ro.build.version.release").strip.to_f
end

#package_name(app_path) ⇒ Object



123
124
125
# File 'lib/flick/android.rb', line 123

def package_name app_path
  manifest(app_path).find {|x| x.name == "package" }["value"]
end

#packagesObject



137
138
139
# File 'lib/flick/android.rb', line 137

def packages
  %x(adb -s #{udid} shell pm list packages).split
end

#pull_file(file, dir) ⇒ Object



166
167
168
# File 'lib/flick/android.rb', line 166

def pull_file file, dir
  %x(adb -s #{udid} pull #{file} #{dir})
end

#pull_files(type) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/flick/android.rb', line 182

def pull_files type
  if unique
    files = unique_files type
  else
    files = %x(adb -s #{udid} shell "ls #{dir_name}/#{type}*").split("\r\n")
  end
  return if files.empty?
  Parallel.map(files, in_threads: 10) do |file| 
    pull_file file, flick_dir
    #Flick::System.wait_for_file 10, "#{flick_dir}/#{file.split("/").last}"
  end
end

#recordable?Boolean

Returns:

  • (Boolean)


154
155
156
157
158
159
160
# File 'lib/flick/android.rb', line 154

def recordable?
  if info[:manufacturer] == "Genymotion"
    return false
  else
    %x(adb -s #{udid} shell "ls /system/bin/screenrecord").strip == "/system/bin/screenrecord"
  end
end

#remove_bad_characters(string) ⇒ Object



23
24
25
# File 'lib/flick/android.rb', line 23

def remove_bad_characters string
  string.gsub(/[\x00\/\\:\*\?\"<>\|]/, '_')
end

#screenrecord(name) ⇒ Object



162
163
164
# File 'lib/flick/android.rb', line 162

def screenrecord name
  %x(adb -s #{udid} shell screenrecord --time-limit #{limit} --size #{size} #{dir_name}/#{name}.mp4)
end

#screenshot(name) ⇒ Object



145
146
147
# File 'lib/flick/android.rb', line 145

def screenshot name
  %x(adb -s #{udid} shell screencap #{dir_name}/#{name}.png)
end

#system_statsObject



77
78
79
80
81
82
83
84
# File 'lib/flick/android.rb', line 77

def system_stats
  x = %x(adb -s #{udid} shell top -n 1 -d 1 | grep System).split(",")
  user = x.find { |x| x.include? "User" }.match(/User (.*)%/)[1].to_i
  sys  = x.find { |x| x.include? "System" }.match(/System (.*)%/)[1].to_i
  iow  = x.find { |x| x.include? "IOW" }.match(/IOW (.*)%/)[1].to_i
  irq  = x.find { |x| x.include? "IRQ" }.match(/IRQ (.*)%/)[1].to_i
  { user: user, system: sys, iow: iow, irq: irq }
end

#uninstall(package) ⇒ Object



110
111
112
113
114
115
116
117
# File 'lib/flick/android.rb', line 110

def uninstall package
  if app_installed? package
    %x(adb -s #{udid} shell pm uninstall #{package})
  else
    puts packages
    puts "\n#{package} was not found on device #{udid}! Please choose one from above. e.g. #{packages.sample}\n".red
  end
end

#unique_files(type) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
# File 'lib/flick/android.rb', line 170

def unique_files type
  if os_version < 6.0
    command = "md5"
  else
    command = "md5sum"
  end
  files = %x(adb -s #{udid} shell "#{command} #{dir_name}/#{type}*")
  hash = files.split("\r\n").map { |file| { md5: file.match(/(.*) /)[1].strip, file: file.match(/ (.*)/)[1].strip } }
  hash.uniq! { |e| e[:md5] }
  hash.map { |file| file[:file] }
end