ruboto 0.5.4 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +9 -9
- data/README.md +2 -0
- data/Rakefile +71 -7
- data/assets/Rakefile +2 -407
- data/assets/libs/dexmaker20120305.jar +0 -0
- data/assets/rakelib/ruboto.rake +428 -0
- data/assets/samples/sample_broadcast_receiver.rb +7 -3
- data/assets/samples/sample_broadcast_receiver_test.rb +47 -1
- data/assets/src/RubotoActivity.java +6 -2
- data/assets/src/org/ruboto/EntryPointActivity.java +2 -2
- data/assets/src/org/ruboto/Script.java +91 -24
- data/assets/src/org/ruboto/test/ActivityTest.java +27 -24
- data/assets/src/org/ruboto/test/InstrumentationTestRunner.java +42 -8
- data/assets/src/ruboto/activity.rb +1 -1
- data/assets/src/ruboto/base.rb +17 -6
- data/assets/src/ruboto/generate.rb +458 -0
- data/assets/src/ruboto/legacy.rb +9 -12
- data/assets/src/ruboto/widget.rb +9 -1
- data/lib/java_class_gen/android_api.xml +1 -1
- data/lib/ruboto.rb +1 -2
- data/lib/ruboto/commands/base.rb +19 -4
- data/lib/ruboto/sdk_versions.rb +12 -0
- data/lib/ruboto/util/build.rb +10 -11
- data/lib/ruboto/util/update.rb +150 -51
- data/lib/ruboto/util/verify.rb +6 -4
- data/lib/ruboto/util/xml_element.rb +2 -2
- data/lib/ruboto/version.rb +1 -1
- data/test/activity/option_menu_activity.rb +5 -1
- data/test/activity/psych_activity.rb +11 -6
- data/test/activity/stack_activity_test.rb +13 -5
- data/test/app_test_methods.rb +4 -3
- data/test/broadcast_receiver_test.rb +86 -0
- data/test/minimal_app_test.rb +27 -19
- data/test/rake_test.rb +13 -2
- data/test/ruboto_gen_test.rb +17 -3
- data/test/ruboto_update_test.rb +24 -2
- data/test/service_test.rb +1 -1
- data/test/test_helper.rb +134 -62
- data/test/update_test_methods.rb +40 -14
- data/test/updated_example_test_methods.rb +41 -0
- metadata +12 -6
Binary file
|
@@ -0,0 +1,428 @@
|
|
1
|
+
if `ant -version` !~ /version (\d+)\.(\d+)\.(\d+)/ || $1.to_i < 1 || ($1.to_i == 1 && $2.to_i < 8)
|
2
|
+
puts "ANT version 1.8.0 or later required. Version found: #{$1}.#{$2}.#{$3}"
|
3
|
+
exit 1
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'time'
|
7
|
+
|
8
|
+
def manifest() @manifest ||= REXML::Document.new(File.read(MANIFEST_FILE)) end
|
9
|
+
def package() manifest.root.attribute('package') end
|
10
|
+
def build_project_name() @build_project_name ||= REXML::Document.new(File.read('build.xml')).elements['project'].attribute(:name).value end
|
11
|
+
def scripts_path() @sdcard_path ||= "/mnt/sdcard/Android/data/#{package}/files/scripts" end
|
12
|
+
def app_files_path() @app_files_path ||= "/data/data/#{package}/files" end
|
13
|
+
|
14
|
+
require 'rake/clean'
|
15
|
+
require 'rexml/document'
|
16
|
+
|
17
|
+
PROJECT_DIR = File.expand_path('..', File.dirname(__FILE__))
|
18
|
+
UPDATE_MARKER_FILE = File.join(PROJECT_DIR, 'bin', 'LAST_UPDATE')
|
19
|
+
BUNDLE_JAR = File.expand_path 'libs/bundle.jar'
|
20
|
+
BUNDLE_PATH = File.expand_path 'bin/bundle'
|
21
|
+
MANIFEST_FILE = File.expand_path 'AndroidManifest.xml'
|
22
|
+
RUBOTO_CONFIG_FILE = File.expand_path 'ruboto.yml'
|
23
|
+
GEM_FILE = File.expand_path('Gemfile.apk')
|
24
|
+
GEM_LOCK_FILE = File.expand_path('Gemfile.apk.lock')
|
25
|
+
RELEASE_APK_FILE = File.expand_path "bin/#{build_project_name}-release.apk"
|
26
|
+
APK_FILE = File.expand_path "bin/#{build_project_name}-debug.apk"
|
27
|
+
TEST_APK_FILE = File.expand_path "test/bin/#{build_project_name}Test-debug.apk"
|
28
|
+
JRUBY_JARS = Dir[File.expand_path 'libs/jruby-*.jar']
|
29
|
+
RESOURCE_FILES = Dir[File.expand_path 'res/**/*']
|
30
|
+
JAVA_SOURCE_FILES = Dir[File.expand_path 'src/**/*.java']
|
31
|
+
RUBY_SOURCE_FILES = Dir[File.expand_path 'src/**/*.rb']
|
32
|
+
APK_DEPENDENCIES = [MANIFEST_FILE, RUBOTO_CONFIG_FILE, BUNDLE_JAR] + JRUBY_JARS + JAVA_SOURCE_FILES + RESOURCE_FILES + RUBY_SOURCE_FILES
|
33
|
+
KEYSTORE_FILE = (key_store = File.readlines('ant.properties').grep(/^key.store=/).first) ? File.expand_path(key_store.chomp.sub(/^key.store=/, '').sub('${user.home}', '~')) : "#{build_project_name}.keystore"
|
34
|
+
KEYSTORE_ALIAS = (key_alias = File.readlines('ant.properties').grep(/^key.alias=/).first) ? key_alias.chomp.sub(/^key.alias=/, '') : build_project_name
|
35
|
+
|
36
|
+
CLEAN.include('bin')
|
37
|
+
|
38
|
+
task :default => :debug
|
39
|
+
|
40
|
+
file JRUBY_JARS => RUBOTO_CONFIG_FILE do
|
41
|
+
next unless File.exists? RUBOTO_CONFIG_FILE
|
42
|
+
jruby_jars_mtime = JRUBY_JARS.map { |f| File.mtime(f) }.min
|
43
|
+
ruboto_yml_mtime = File.mtime(RUBOTO_CONFIG_FILE)
|
44
|
+
next if jruby_jars_mtime > ruboto_yml_mtime
|
45
|
+
puts '*' * 80
|
46
|
+
if JRUBY_JARS.empty?
|
47
|
+
puts ' The JRuby jars are missing.'
|
48
|
+
else
|
49
|
+
puts " The JRuby jars need reconfiguring after changes to #{RUBOTO_CONFIG_FILE}"
|
50
|
+
puts " #{RUBOTO_CONFIG_FILE}: #{ruboto_yml_mtime}"
|
51
|
+
puts " #{JRUBY_JARS.join(', ')}: #{jruby_jars_mtime}"
|
52
|
+
end
|
53
|
+
puts ' Run "ruboto update jruby" to regenerate the JRuby jars'
|
54
|
+
puts '*' * 80
|
55
|
+
end
|
56
|
+
|
57
|
+
desc 'build debug package'
|
58
|
+
task :debug => APK_FILE
|
59
|
+
|
60
|
+
namespace :debug do
|
61
|
+
desc 'build debug package if compiled files have changed'
|
62
|
+
task :quick => [MANIFEST_FILE, RUBOTO_CONFIG_FILE, BUNDLE_JAR] + JRUBY_JARS + JAVA_SOURCE_FILES + RESOURCE_FILES do |t|
|
63
|
+
build_apk(t, false)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "build package and install it on the emulator or device"
|
68
|
+
task :install => APK_FILE do
|
69
|
+
install_apk
|
70
|
+
end
|
71
|
+
|
72
|
+
namespace :install do
|
73
|
+
desc 'uninstall, build, and install the application'
|
74
|
+
task :clean => [:uninstall, APK_FILE, :install]
|
75
|
+
|
76
|
+
desc 'Install the application, but only if compiled files are changed.'
|
77
|
+
task :quick => 'debug:quick' do
|
78
|
+
install_apk
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
desc 'Build APK for release'
|
83
|
+
task :release => RELEASE_APK_FILE
|
84
|
+
|
85
|
+
file RELEASE_APK_FILE => [KEYSTORE_FILE] + APK_DEPENDENCIES do |t|
|
86
|
+
build_apk(t, true)
|
87
|
+
end
|
88
|
+
|
89
|
+
desc 'Create a keystore for signing the release APK'
|
90
|
+
file KEYSTORE_FILE do
|
91
|
+
unless File.read('ant.properties') =~ /^key.store=/
|
92
|
+
File.open('ant.properties', 'a'){|f| f << "\nkey.store=#{KEYSTORE_FILE}\n"}
|
93
|
+
end
|
94
|
+
unless File.read('ant.properties') =~ /^key.alias=/
|
95
|
+
File.open('ant.properties', 'a'){|f| f << "\nkey.alias=#{KEYSTORE_ALIAS}\n"}
|
96
|
+
end
|
97
|
+
sh "keytool -genkey -v -keystore #{KEYSTORE_FILE} -alias #{KEYSTORE_ALIAS} -keyalg RSA -keysize 2048 -validity 10000"
|
98
|
+
end
|
99
|
+
|
100
|
+
desc 'Tag this working copy with the current version'
|
101
|
+
task :tag => :release do
|
102
|
+
unless `git branch` =~ /^\* master$/
|
103
|
+
puts "You must be on the master branch to release!"
|
104
|
+
exit!
|
105
|
+
end
|
106
|
+
# sh "git commit --allow-empty -a -m 'Release #{version}'"
|
107
|
+
output = `git status --porcelain`
|
108
|
+
raise "Workspace not clean!\n#{output}" unless output.empty?
|
109
|
+
sh "git tag #{version}"
|
110
|
+
sh "git push origin master --tags"
|
111
|
+
end
|
112
|
+
|
113
|
+
task :sign => :release do
|
114
|
+
sh "jarsigner -keystore #{ENV['RUBOTO_KEYSTORE']} -signedjar bin/#{build_project_name}.apk bin/#{build_project_name}-unsigned.apk #{ENV['RUBOTO_KEY_ALIAS']}"
|
115
|
+
end
|
116
|
+
|
117
|
+
task :align => :sign do
|
118
|
+
sh "zipalign 4 bin/#{build_project_name}.apk #{build_project_name}.apk"
|
119
|
+
end
|
120
|
+
|
121
|
+
task :publish => :align do
|
122
|
+
puts "#{build_project_name}.apk is ready for the market!"
|
123
|
+
end
|
124
|
+
|
125
|
+
desc 'Start the emulator with larger disk'
|
126
|
+
task :emulator do
|
127
|
+
sh 'emulator -partition-size 1024 -avd Android_3.0'
|
128
|
+
end
|
129
|
+
|
130
|
+
task :start do
|
131
|
+
start_app
|
132
|
+
end
|
133
|
+
|
134
|
+
task :stop do
|
135
|
+
raise "Unable to stop app. Only available on emulator." unless stop_app
|
136
|
+
end
|
137
|
+
|
138
|
+
desc 'Restart the application'
|
139
|
+
task :restart => [:stop, :start]
|
140
|
+
|
141
|
+
task :uninstall do
|
142
|
+
uninstall_apk
|
143
|
+
end
|
144
|
+
|
145
|
+
file MANIFEST_FILE
|
146
|
+
file RUBOTO_CONFIG_FILE
|
147
|
+
|
148
|
+
file APK_FILE => APK_DEPENDENCIES do |t|
|
149
|
+
build_apk(t, false)
|
150
|
+
end
|
151
|
+
|
152
|
+
desc 'Copy scripts to emulator or device'
|
153
|
+
task :update_scripts => ['install:quick'] do
|
154
|
+
update_scripts
|
155
|
+
end
|
156
|
+
|
157
|
+
namespace :update_scripts do
|
158
|
+
desc 'Copy scripts to emulator and restart the app'
|
159
|
+
task :restart => APK_DEPENDENCIES do |t|
|
160
|
+
if build_apk(t, false) || !stop_app
|
161
|
+
install_apk
|
162
|
+
else
|
163
|
+
update_scripts
|
164
|
+
end
|
165
|
+
start_app
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
task :test => :uninstall do
|
170
|
+
Dir.chdir('test') do
|
171
|
+
puts 'Running tests'
|
172
|
+
sh "adb uninstall #{package}.tests"
|
173
|
+
sh "ant instrument install test"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
namespace :test do
|
178
|
+
task :quick => :update_scripts do
|
179
|
+
Dir.chdir('test') do
|
180
|
+
puts 'Running quick tests'
|
181
|
+
sh 'ant instrument'
|
182
|
+
sh 'ant installi'
|
183
|
+
sh "ant run-tests-quick"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
file GEM_FILE
|
189
|
+
file GEM_LOCK_FILE
|
190
|
+
|
191
|
+
desc 'Generate bundle jar from Gemfile'
|
192
|
+
task :bundle => BUNDLE_JAR
|
193
|
+
|
194
|
+
file BUNDLE_JAR => [GEM_FILE, GEM_LOCK_FILE] do
|
195
|
+
next unless File.exists? GEM_FILE
|
196
|
+
puts "Generating #{BUNDLE_JAR}"
|
197
|
+
|
198
|
+
FileUtils.mkdir_p BUNDLE_PATH
|
199
|
+
sh "bundle install --gemfile #{GEM_FILE} --path=#{BUNDLE_PATH}"
|
200
|
+
gem_path = Dir["#{BUNDLE_PATH}/*ruby/1.8/gems"][0]
|
201
|
+
|
202
|
+
if package != 'org.ruboto.core' && JRUBY_JARS.none? { |f| File.exists? f }
|
203
|
+
Dir.chdir gem_path do
|
204
|
+
Dir['{activerecord-jdbc-adapter, jruby-openssl}-*'].each do |g|
|
205
|
+
puts "Removing #{g} gem since it is included in the RubotoCore platform apk."
|
206
|
+
FileUtils.rm_rf g
|
207
|
+
end
|
208
|
+
end
|
209
|
+
else
|
210
|
+
Dir.chdir gem_path do
|
211
|
+
Dir['jruby-openssl-*/lib'].each do |g|
|
212
|
+
rel_dir = "#{g}/lib/ruby"
|
213
|
+
unless File.exists? rel_dir
|
214
|
+
puts "Relocating #{g} files to match standard load path."
|
215
|
+
dirs = Dir["#{g}/*"]
|
216
|
+
FileUtils.mkdir_p rel_dir
|
217
|
+
dirs.each do |d|
|
218
|
+
FileUtils.move d, rel_dir
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# Remove duplicate files
|
226
|
+
Dir.chdir gem_path do
|
227
|
+
scanned_files = []
|
228
|
+
source_files = RUBY_SOURCE_FILES.map { |f| f.gsub("#{PROJECT_DIR}/src/", '') }
|
229
|
+
Dir["*/lib/**/*"].each do |f|
|
230
|
+
next if File.directory? f
|
231
|
+
raise "Malformed file name" unless f =~ %r{^(.*?)/lib/(.*)$}
|
232
|
+
gem_name, lib_file = $1, $2
|
233
|
+
if existing_file = scanned_files.find { |sf| sf =~ %r{(.*?)/lib/#{lib_file}} }
|
234
|
+
puts "Overwriting duplicate file #{lib_file} in gem #{$1} with file in #{gem_name}"
|
235
|
+
FileUtils.rm existing_file
|
236
|
+
scanned_files.delete existing_file
|
237
|
+
elsif source_files.include? lib_file
|
238
|
+
puts "Removing duplicate file #{lib_file} in gem #{gem_name}"
|
239
|
+
puts "Already present in project source src/#{lib_file}"
|
240
|
+
FileUtils.rm f
|
241
|
+
next
|
242
|
+
end
|
243
|
+
scanned_files << f
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
# Expand JARs
|
248
|
+
Dir.chdir gem_path do
|
249
|
+
Dir['*'].each do |gem_lib|
|
250
|
+
Dir.chdir "#{gem_lib}/lib" do
|
251
|
+
Dir['**/*.jar'].each do |jar|
|
252
|
+
if jar == 'arjdbc/jdbc/adapter_java.jar'
|
253
|
+
jar_load_code = <<-END_CODE
|
254
|
+
require 'jruby'
|
255
|
+
Java::arjdbc.jdbc.AdapterJavaService.new.basicLoad(JRuby.runtime)
|
256
|
+
END_CODE
|
257
|
+
elsif jar =~ /shared\/jopenssl.jar$/
|
258
|
+
jar_load_code = <<-END_CODE
|
259
|
+
require 'jruby'
|
260
|
+
puts 'Starting JRuby OpenSSL Service'
|
261
|
+
public
|
262
|
+
Java::JopensslService.new.basicLoad(JRuby.runtime)
|
263
|
+
END_CODE
|
264
|
+
else
|
265
|
+
jar_load_code = ''
|
266
|
+
end
|
267
|
+
unless jar =~ /sqlite-jdbc/
|
268
|
+
puts "Expanding #{gem_lib} #{jar} into #{BUNDLE_JAR}"
|
269
|
+
`jar xf #{jar}`
|
270
|
+
end
|
271
|
+
puts "Writing dummy JAR file #{jar + '.rb'}"
|
272
|
+
File.open(jar + '.rb', 'w') { |f| f << jar_load_code }
|
273
|
+
if jar.end_with?('.jar')
|
274
|
+
puts "Writing dummy JAR file #{jar.sub(/.jar$/, '.rb')}"
|
275
|
+
File.open(jar.sub(/.jar$/, '.rb'), 'w') { |f| f << jar_load_code }
|
276
|
+
end
|
277
|
+
FileUtils.rm_f(jar)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
|
284
|
+
FileUtils.rm_f BUNDLE_JAR
|
285
|
+
Dir["#{gem_path}/*"].each_with_index do |gem_dir, i|
|
286
|
+
`jar #{i == 0 ? 'c' : 'u'}f #{BUNDLE_JAR} -C #{gem_dir}/lib .`
|
287
|
+
end
|
288
|
+
FileUtils.rm_rf BUNDLE_PATH
|
289
|
+
end
|
290
|
+
|
291
|
+
# Methods
|
292
|
+
|
293
|
+
def mark_update(time = Time.now)
|
294
|
+
FileUtils.mkdir_p File.dirname(UPDATE_MARKER_FILE)
|
295
|
+
File.open(UPDATE_MARKER_FILE, 'w') { |f| f << time.iso8601 }
|
296
|
+
end
|
297
|
+
|
298
|
+
def clear_update
|
299
|
+
mark_update File.ctime APK_FILE
|
300
|
+
if device_path_exists?(scripts_path)
|
301
|
+
sh "adb shell rm -r #{scripts_path}"
|
302
|
+
puts "Deleted scripts directory #{scripts_path}"
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
def strings(name)
|
307
|
+
@strings ||= REXML::Document.new(File.read('res/values/strings.xml'))
|
308
|
+
value = @strings.elements["//string[@name='#{name.to_s}']"] or raise "string '#{name}' not found in strings.xml"
|
309
|
+
value.text
|
310
|
+
end
|
311
|
+
|
312
|
+
def version()
|
313
|
+
strings :version_name
|
314
|
+
end
|
315
|
+
|
316
|
+
def app_name()
|
317
|
+
strings :app_name
|
318
|
+
end
|
319
|
+
|
320
|
+
def main_activity()
|
321
|
+
manifest.root.elements['application'].elements["activity[@android:label='@string/app_name']"].attribute('android:name')
|
322
|
+
end
|
323
|
+
|
324
|
+
def device_path_exists?(path)
|
325
|
+
path_output =`adb shell ls #{path}`
|
326
|
+
result = path_output.chomp !~ /No such file or directory|opendir failed, Permission denied/
|
327
|
+
result
|
328
|
+
end
|
329
|
+
|
330
|
+
def package_installed? test = false
|
331
|
+
package_name = "#{package}#{'.tests' if test}"
|
332
|
+
['', '-0', '-1', '-2'].each do |i|
|
333
|
+
p = "/data/app/#{package_name}#{i}.apk"
|
334
|
+
o = `adb shell ls -l #{p}`.chomp
|
335
|
+
if o =~ /^-rw-r--r-- system\s+system\s+(\d+) \d{4}-\d{2}-\d{2} \d{2}:\d{2} #{File.basename(p)}$/
|
336
|
+
apk_file = test ? TEST_APK_FILE : APK_FILE
|
337
|
+
if !File.exists?(apk_file) || $1.to_i == File.size(apk_file)
|
338
|
+
return true
|
339
|
+
else
|
340
|
+
return false
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
return nil
|
345
|
+
end
|
346
|
+
|
347
|
+
private
|
348
|
+
|
349
|
+
def replace_faulty_code(faulty_file, faulty_code)
|
350
|
+
explicit_requires = Dir["#{faulty_file.chomp('.rb')}/*.rb"].sort.map { |f| File.basename(f) }.map do |filename|
|
351
|
+
"require 'active_model/validations/#{filename}'"
|
352
|
+
end.join("\n")
|
353
|
+
|
354
|
+
old_code = File.read(faulty_file)
|
355
|
+
new_code = old_code.gsub faulty_code, explicit_requires
|
356
|
+
if new_code != old_code
|
357
|
+
puts "Replaced directory listing code in file #{faulty_file} with explicit requires."
|
358
|
+
File.open(faulty_file, 'w') { |f| f << new_code }
|
359
|
+
else
|
360
|
+
puts "Could not find expected faulty code\n\n#{faulty_code}\n\nin file #{faulty_file}\n\n#{old_code}\n\n"
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
def build_apk(t, release)
|
365
|
+
apk_file = release ? RELEASE_APK_FILE : APK_FILE
|
366
|
+
if File.exist?(apk_file)
|
367
|
+
changed_prereqs = t.prerequisites.select do |p|
|
368
|
+
File.file?(p) && !Dir[p].empty? && Dir[p].map { |f| File.mtime(f) }.max > File.mtime(APK_FILE)
|
369
|
+
end
|
370
|
+
return false if changed_prereqs.empty?
|
371
|
+
changed_prereqs.each { |f| puts "#{f} changed." }
|
372
|
+
puts "Forcing rebuild of #{apk_file}."
|
373
|
+
end
|
374
|
+
if release
|
375
|
+
sh 'ant release'
|
376
|
+
else
|
377
|
+
sh 'ant debug'
|
378
|
+
end
|
379
|
+
return true
|
380
|
+
end
|
381
|
+
|
382
|
+
def install_apk
|
383
|
+
case package_installed?
|
384
|
+
when true
|
385
|
+
puts "Package #{package} already installed."
|
386
|
+
return
|
387
|
+
when false
|
388
|
+
puts "Package installed, but of wrong size."
|
389
|
+
end
|
390
|
+
sh 'ant installd'
|
391
|
+
clear_update
|
392
|
+
end
|
393
|
+
|
394
|
+
def uninstall_apk
|
395
|
+
return if package_installed?.nil?
|
396
|
+
puts "Uninstalling package #{package}"
|
397
|
+
system "adb uninstall #{package}"
|
398
|
+
if $? != 0 && package_installed?
|
399
|
+
puts "Uninstall failed exit code #{$?}"
|
400
|
+
exit $?
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
def update_scripts
|
405
|
+
`adb shell mkdir -p #{scripts_path}` if !device_path_exists?(scripts_path)
|
406
|
+
puts "Pushing files to apk public file area."
|
407
|
+
last_update = File.exists?(UPDATE_MARKER_FILE) ? Time.parse(File.read(UPDATE_MARKER_FILE)) : Time.parse('1970-01-01T00:00:00')
|
408
|
+
# TODO(uwe): Use `adb sync src` instead?
|
409
|
+
Dir.chdir('src') do
|
410
|
+
Dir["**/*.rb"].each do |script_file|
|
411
|
+
next if File.directory? script_file
|
412
|
+
next if File.mtime(script_file) < last_update
|
413
|
+
next if script_file =~ /~$/
|
414
|
+
print "#{script_file}: "; $stdout.flush
|
415
|
+
`adb push #{script_file} #{scripts_path}/#{script_file}`
|
416
|
+
end
|
417
|
+
end
|
418
|
+
mark_update
|
419
|
+
end
|
420
|
+
|
421
|
+
def start_app
|
422
|
+
`adb shell am start -a android.intent.action.MAIN -n #{package}/.#{main_activity}`
|
423
|
+
end
|
424
|
+
|
425
|
+
def stop_app
|
426
|
+
output = `adb shell ps | grep #{package} | awk '{print $2}' | xargs adb shell kill`
|
427
|
+
return output !~ /Operation not permitted/
|
428
|
+
end
|
@@ -1,9 +1,13 @@
|
|
1
1
|
require 'ruboto/broadcast_receiver'
|
2
2
|
|
3
|
-
|
3
|
+
import android.util.Log
|
4
|
+
|
4
5
|
RubotoBroadcastReceiver.new_with_callbacks do
|
6
|
+
# will get called whenever the BroadcastReceiver receives an intent (whenever onReceive is called)
|
5
7
|
def on_receive(context, intent)
|
6
|
-
Log.v "
|
8
|
+
Log.v "SampleBroadcastReceiver", 'Broadcast received!'
|
9
|
+
Log.v "SampleBroadcastReceiver", intent.getExtras.to_s
|
10
|
+
context.run_on_ui_thread{$activity.title = 'Broadcast received!'}
|
11
|
+
Log.v "SampleBroadcastReceiver", 'Broadcast processed OK!'
|
7
12
|
end
|
8
13
|
end
|
9
|
-
|
@@ -1 +1,47 @@
|
|
1
|
-
#
|
1
|
+
# Change this to the activity that will send the broadcast
|
2
|
+
activity Java::THE_PACKAGE.SampleActivity
|
3
|
+
|
4
|
+
# Change this to wait for the activity to be created
|
5
|
+
setup do |activity|
|
6
|
+
start = Time.now
|
7
|
+
loop do
|
8
|
+
@text_view = activity.findViewById(42)
|
9
|
+
break if @text_view || (Time.now - start > 60)
|
10
|
+
sleep 1
|
11
|
+
end
|
12
|
+
assert @text_view
|
13
|
+
end
|
14
|
+
|
15
|
+
# Change this to trigger the sending of broadcast intents
|
16
|
+
# and assert that the receiver behaves correctly.
|
17
|
+
test('broadcast changes title', :ui => false) do |activity|
|
18
|
+
begin
|
19
|
+
@receiver = $package.SampleBroadcastReceiver.new
|
20
|
+
action = '__THE_PACKAGE__.SampleBroadcastReceiver.action'
|
21
|
+
filter = android.content.IntentFilter.new(action)
|
22
|
+
receiver_ready = false
|
23
|
+
Thread.start do
|
24
|
+
begin
|
25
|
+
android.os.Looper.prepare
|
26
|
+
activity.registerReceiver(@receiver, filter, nil, android.os.Handler.new)
|
27
|
+
receiver_ready = true
|
28
|
+
android.os.Looper.loop
|
29
|
+
rescue
|
30
|
+
puts "Exception starting receiver"
|
31
|
+
puts $!.message
|
32
|
+
puts $!.backtrace.join("\n")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
sleep 0.1 until receiver_ready
|
36
|
+
intent = android.content.Intent.new
|
37
|
+
intent.set_action action
|
38
|
+
activity.send_broadcast(intent)
|
39
|
+
bc_sent_at = Time.now
|
40
|
+
|
41
|
+
message = 'Broadcast received!'
|
42
|
+
sleep 0.1 until activity.title == message || (Time.now - bc_sent_at) > 10
|
43
|
+
assert_equal message, activity.title
|
44
|
+
ensure
|
45
|
+
activity.unregister_receiver(@receiver) if @receiver
|
46
|
+
end
|
47
|
+
end
|