ruboto 0.8.1 → 0.9.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -142,6 +142,80 @@ task :release_docs do
142
142
  puts "* https://github.com/ruboto/ruboto/issues?state=closed&milestone=#{milestone}\n\n"
143
143
  end
144
144
 
145
+ desc 'Fetch download stats form rubygems.org'
146
+ task :stats do
147
+ require 'rubygems'
148
+ require 'uri'
149
+ require 'net/http'
150
+ require 'net/https'
151
+ require 'openssl'
152
+ require 'yaml'
153
+ host = 'rubygems.org'
154
+ base_uri = "https://#{host}/api/v1"
155
+ https = Net::HTTP.new(host, 443)
156
+ https.use_ssl = true
157
+ https.verify_mode = OpenSSL::SSL::VERIFY_NONE
158
+
159
+ counts_per_month = Hash.new{|h, k| h[k] = Hash.new{|mh,mk| mh[mk] = 0 }}
160
+ total = 0
161
+
162
+ %w{ruboto-core ruboto}.each do |gem|
163
+ versions_uri = URI("#{base_uri}/versions/#{gem}.yaml")
164
+ req = Net::HTTP::Get.new(versions_uri.request_uri)
165
+ res = https.start { |http| http.request(req) }
166
+ versions = YAML.load(res.body).sort_by { |v| Gem::Version.new(v['number']) }
167
+ puts "\n#{gem}:\n#{versions.map { |v| "#{'%10s' % v['number']} #{v['downloads_count']}" }.join("\n")}"
168
+
169
+ versions.each do |v|
170
+ downloads_uri = URI("#{base_uri}/versions/#{gem}-#{v['number']}/downloads/search.yaml?from=2010-08-01&to=#{Date.today}")
171
+ req = Net::HTTP::Get.new(downloads_uri.request_uri)
172
+ res = https.start { |http| http.request(req) }
173
+ counts = YAML.load(res.body)
174
+ counts.each do |date_str, count|
175
+ date = Date.parse(date_str)
176
+ counts_per_month[date.year][date.month] += count
177
+ total += count
178
+ end
179
+ print '.' ; STDOUT.flush
180
+ end
181
+ puts
182
+ end
183
+
184
+ puts "\nDownloads statistics per month:"
185
+ years = counts_per_month.keys
186
+ puts "\n #{years.map{|year| '%6s:' % year}.join(' ')}"
187
+ (1..12).each do |month|
188
+ print "#{'%2d' % month}:"
189
+ years.each do |year|
190
+ count = counts_per_month[year][month]
191
+ print count > 0 ? '%8d' % count : ' ' * 8
192
+ end
193
+ puts
194
+ end
195
+
196
+ puts "\nTotal: #{total}\n\n"
197
+
198
+ puts "\nRubyGems download statistics per month:"
199
+ years = counts_per_month.keys
200
+ puts ' ' + years.map{|year| '%-12s' % year}.join
201
+ (0..20).each do |l|
202
+ print (l % 10 == 0) ? '%4d' % ((20-l) * 100) : ' '
203
+ years.each do |year|
204
+ (1..12).each do |month|
205
+ count = counts_per_month[year][month]
206
+ if [year, month] == [Date.today.year, Date.today.month]
207
+ count *= (Date.new(Date.today.year, Date.today.month, -1).day.to_f / Date.today.day).to_i
208
+ end
209
+ print count > ((20-l) * 100) ? '*' : ' '
210
+ end
211
+ end
212
+ puts
213
+ end
214
+ puts ' ' + years.map{|year| '%-12s' % year}.join
215
+
216
+ puts "\nTotal: #{total}\n\n"
217
+ end
218
+
145
219
  desc "Push the gem to RubyGems"
146
220
  task :release => [:clean, :gem] do
147
221
  output = `git status --porcelain`
@@ -180,7 +254,7 @@ namespace :platform do
180
254
  Dir.chdir(PLATFORM_PROJECT) do
181
255
  manifest = REXML::Document.new(File.read(MANIFEST_FILE))
182
256
  manifest.root.attributes['android:versionCode'] = '408'
183
- manifest.root.attributes['android:versionName'] = '0.4.8.dev'
257
+ manifest.root.attributes['android:versionName'] = '0.4.8'
184
258
  manifest.root.attributes['android:installLocation'] = 'auto' # or 'preferExternal' ?
185
259
  File.open(MANIFEST_FILE, 'w') { |f| manifest.document.write(f, 4) }
186
260
  File.open('Gemfile.apk', 'w'){|f| f << "source :rubygems\n\ngem 'activerecord-jdbc-adapter'\n"}
Binary file
@@ -238,7 +238,8 @@ public class JRubyAdapter {
238
238
  // END Ruboto HeapAlloc
239
239
  setDebugBuild(appContext);
240
240
  Log.d("Setting up JRuby runtime (" + (isDebugBuild ? "DEBUG" : "RELEASE") + ")");
241
- System.setProperty("jruby.compile.mode", "OFF"); // OFF OFFIR
241
+ System.setProperty("jruby.compile.mode", "OFF"); // OFF OFFIR JITIR? FORCEIR
242
+ // System.setProperty("jruby.compile.backend", "DALVIK");
242
243
  System.setProperty("jruby.bytecode.version", "1.6");
243
244
  System.setProperty("jruby.interfaces.useProxy", "true");
244
245
  System.setProperty("jruby.management.enabled", "false");
@@ -253,6 +254,10 @@ public class JRubyAdapter {
253
254
  // System.setProperty("jruby.debug.loadService", "true");
254
255
  // System.setProperty("jruby.debug.loadService.timing", "true");
255
256
 
257
+ // Used to enable JRuby to generate proxy classes
258
+ System.setProperty("jruby.ji.proxyClassFactory", "org.ruboto.DalvikProxyClassFactory");
259
+ System.setProperty("jruby.class.cache.path", appContext.getDir("dex", 0).getAbsolutePath());
260
+
256
261
  ClassLoader classLoader;
257
262
  Class<?> scriptingContainerClass;
258
263
  String apkName = null;
@@ -40,9 +40,9 @@ public class Script {
40
40
  public static String toSnakeCase(String s) {
41
41
  return s.replaceAll(
42
42
  String.format("%s|%s|%s",
43
- "(?<=[A-Z])(?=[A-Z][a-z])",
43
+ "(?<=[A-Z])(?=[A-Z][a-z0-9])",
44
44
  "(?<=[^A-Z])(?=[A-Z])",
45
- "(?<=[A-Za-z])(?=[^A-Za-z])"
45
+ "(?<=[A-Za-z0-9])(?=[^A-Za-z0-9])"
46
46
  ),
47
47
  "_"
48
48
  ).replace("__", "_").toLowerCase();
@@ -0,0 +1,107 @@
1
+ package org.ruboto;
2
+
3
+ import java.io.File;
4
+ import java.io.FileOutputStream;
5
+ import java.io.IOException;
6
+ import java.io.OutputStream;
7
+ import java.lang.reflect.Constructor;
8
+ import java.lang.reflect.Field;
9
+ import java.lang.reflect.InvocationTargetException;
10
+ import java.lang.reflect.Method;
11
+ import java.lang.reflect.Modifier;
12
+ import java.lang.reflect.UndeclaredThrowableException;
13
+ import java.security.AccessController;
14
+ import java.security.PrivilegedAction;
15
+ import java.security.ProtectionDomain;
16
+ import java.util.Arrays;
17
+ import java.util.HashMap;
18
+ import java.util.HashSet;
19
+ import java.util.Iterator;
20
+ import java.util.Map;
21
+ import java.util.Set;
22
+ import java.util.TreeMap;
23
+ import java.util.jar.Attributes;
24
+ import java.util.jar.JarEntry;
25
+ import java.util.jar.JarOutputStream;
26
+ import java.util.jar.Manifest;
27
+
28
+ import com.android.dx.Version;
29
+ import com.headius.android.dex.DexClient;
30
+
31
+ import dalvik.system.DexClassLoader;
32
+
33
+ public class DalvikProxyClassFactory extends org.jruby.javasupport.proxy.JavaProxyClassFactory {
34
+ private static final String DEX_IN_JAR_NAME = "classes.dex";
35
+ private static final Attributes.Name CREATED_BY = new Attributes.Name("Created-By");
36
+
37
+ public Class invokeDefineClass(ClassLoader loader, String className, byte[] data) {
38
+ String cachePath = System.getProperty("jruby.class.cache.path");
39
+ if (cachePath != null) {
40
+ byte[] dalvikByteCode = new DexClient().classesToDex(
41
+ new String[] { className.replace('.', '/') + ".class" }, new byte[][] { data });
42
+ String jarFileName = cachePath + "/" + className.replace('.', '/') + ".jar";
43
+ createJar(jarFileName, dalvikByteCode);
44
+ try {
45
+ return new DexClassLoader(jarFileName, cachePath, null, loader)
46
+ .loadClass(className);
47
+ } catch (ClassNotFoundException e1) {
48
+ System.out.println("Exception loading class with DexClassLoader: " + e1);
49
+ e1.printStackTrace();
50
+ }
51
+ }
52
+ return null;
53
+ }
54
+
55
+ private static boolean createJar(String fileName, byte[] dexArray) {
56
+ File parentFile = new File(fileName).getParentFile();
57
+ if (!parentFile.exists()) {
58
+ System.out.println("Creating directory: " + parentFile);
59
+ parentFile.mkdirs();
60
+ }
61
+ try {
62
+ TreeMap<String, byte[]> outputResources = new TreeMap<String, byte[]>();
63
+ Manifest manifest = makeManifest();
64
+ OutputStream out = (fileName.equals("-") || fileName.startsWith("-.")) ? System.out
65
+ : new FileOutputStream(fileName);
66
+ JarOutputStream jarOut = new JarOutputStream(out, manifest);
67
+ outputResources.put(DEX_IN_JAR_NAME, dexArray);
68
+ try {
69
+ for (Map.Entry<String, byte[]> e : outputResources.entrySet()) {
70
+ String name = e.getKey();
71
+ byte[] contents = e.getValue();
72
+ JarEntry entry = new JarEntry(name);
73
+ entry.setSize(contents.length);
74
+ jarOut.putNextEntry(entry);
75
+ jarOut.write(contents);
76
+ jarOut.closeEntry();
77
+ }
78
+ } finally {
79
+ jarOut.finish();
80
+ jarOut.flush();
81
+ if (out != null) {
82
+ out.flush();
83
+ if (out != System.out) {
84
+ out.close();
85
+ }
86
+ }
87
+ jarOut.close();
88
+ }
89
+ } catch (Exception ex) {
90
+ System.out.println("Exception writing jar: " + fileName);
91
+ System.out.println("Exception writing jar: " + ex);
92
+ ex.printStackTrace();
93
+ return false;
94
+ }
95
+ return true;
96
+ }
97
+
98
+ private static Manifest makeManifest() throws IOException {
99
+ Manifest manifest = new Manifest();
100
+ Attributes attribs = manifest.getMainAttributes();
101
+ attribs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
102
+ attribs.put(CREATED_BY, "dx " + Version.VERSION);
103
+ attribs.putValue("Dex-Location", DEX_IN_JAR_NAME);
104
+ return manifest;
105
+ }
106
+
107
+ }
@@ -0,0 +1,85 @@
1
+ package com.headius.android.dex;
2
+
3
+ import java.io.ByteArrayOutputStream;
4
+ import java.io.OutputStreamWriter;
5
+
6
+ import com.android.dx.cf.iface.ParseException;
7
+ import com.android.dx.dex.cf.CfOptions;
8
+ import com.android.dx.dex.cf.CfTranslator;
9
+ import com.android.dx.dex.code.PositionList;
10
+ import com.android.dx.dex.file.ClassDefItem;
11
+ import com.android.dx.dex.file.DexFile;
12
+
13
+ public class DexClient {
14
+ /** {@code non-null;} output file in-progress */
15
+ private static DexFile outputDex;
16
+
17
+ private final CfOptions cfOptions;
18
+
19
+ public DexClient() {
20
+ outputDex = new DexFile();
21
+ cfOptions = new CfOptions();
22
+
23
+ cfOptions.positionInfo = PositionList.LINES;
24
+ cfOptions.localInfo = true;
25
+ cfOptions.strictNameCheck = true;
26
+ cfOptions.optimize = false;
27
+ cfOptions.optimizeListFile = null;
28
+ cfOptions.dontOptimizeListFile = null;
29
+ cfOptions.statistics = false;
30
+ }
31
+
32
+ public byte[] classesToDex(String[] names, byte[][] byteArrays) {
33
+ for (int i = 0; i < names.length; i++) {
34
+ String name = names[i];
35
+ byte[] byteArray = byteArrays[i];
36
+ processClass(name, byteArray);
37
+ }
38
+
39
+ byte[] outputArray = writeDex();
40
+
41
+ return outputArray;
42
+ }
43
+
44
+ /**
45
+ * Processes one classfile.
46
+ *
47
+ * @param name {@code non-null;} name of the file, clipped such that it
48
+ * <i>should</i> correspond to the name of the class it contains
49
+ * @param bytes {@code non-null;} contents of the file
50
+ * @return whether processing was successful
51
+ */
52
+ private boolean processClass(String name, byte[] bytes) {
53
+ try {
54
+ ClassDefItem clazz =
55
+ CfTranslator.translate(name, bytes, cfOptions);
56
+ outputDex.add(clazz);
57
+ return true;
58
+ } catch (ParseException ex) {
59
+ ex.printStackTrace();
60
+ }
61
+
62
+ return false;
63
+ }
64
+
65
+ /**
66
+ * Converts {@link #outputDex} into a {@code byte[]}, write
67
+ * it out to the proper file (if any), and also do whatever human-oriented
68
+ * dumping is required.
69
+ *
70
+ * @return {@code null-ok;} the converted {@code byte[]} or {@code null}
71
+ * if there was a problem
72
+ */
73
+ private byte[] writeDex() {
74
+ byte[] outArray = null;
75
+
76
+ OutputStreamWriter out = new OutputStreamWriter(new ByteArrayOutputStream());
77
+ try {
78
+ outArray = outputDex.toDex(out, false);
79
+ } catch (Exception ex) {
80
+ ex.printStackTrace();
81
+ }
82
+
83
+ return outArray;
84
+ }
85
+ }
@@ -97,7 +97,7 @@ module Ruboto
97
97
  update_icons true
98
98
  update_classes nil, true
99
99
  update_jruby true if params['with-jruby'].value
100
- update_dexmaker true unless params['with-jruby'].value
100
+ update_dx_jar true unless params['with-jruby'].value
101
101
  update_core_classes "exclude"
102
102
 
103
103
  log_action("Generating the default Activity and script") do
@@ -358,7 +358,7 @@ module Ruboto
358
358
  update_assets
359
359
  update_ruboto force
360
360
  update_classes old_version, force
361
- update_dexmaker force
361
+ update_dx_jar force
362
362
  update_jruby force
363
363
  update_manifest nil, nil, force
364
364
  update_icons force
@@ -14,21 +14,9 @@ module Ruboto
14
14
  def update_android
15
15
  root = Dir.getwd
16
16
  build_xml_file = "#{root}/build.xml"
17
- new_prop_file = "#{root}/project.properties"
18
- old_prop_file = "#{root}/default.properties"
19
17
  name = REXML::Document.new(File.read(build_xml_file)).root.attributes['name']
20
18
 
21
- # FIXME(uwe): Remove build.xml file to force regeneration.
22
- # FIXME(uwe): Needed when updating apps from Android SDK <= 13 to 14
23
- # FIXME(uwe): Remove when we stop supporting upgrading apps from Android SDK <= 13
24
- if File.read(build_xml_file) !~ /<!-- version-tag: 1 -->/
25
- puts "Forcing generation of new build.xml since upgrading a project generated with Android SDK 13 or older."
26
- FileUtils.rm_f build_xml_file
27
- end
28
- # EMXIF
29
-
30
- # FIXME(uwe): Simplify when we stop supporting upgrading apps from Android SDK <= 13
31
- prop_file = File.exists?(new_prop_file) ? new_prop_file : old_prop_file
19
+ prop_file = "#{root}/project.properties"
32
20
  version_regexp = /^(target=android-)(\d+)$/
33
21
  if (project_property_file = File.read(prop_file)) =~ version_regexp
34
22
  if $2.to_i < MINIMUM_SUPPORTED_SDK_LEVEL
@@ -36,9 +24,8 @@ module Ruboto
36
24
  File.open(prop_file, 'w') { |f| f << project_property_file.gsub(version_regexp, "\\1#{MINIMUM_SUPPORTED_SDK_LEVEL}") }
37
25
  end
38
26
  end
39
- # EMXIF
40
27
 
41
- system "android update project -p #{root} -n #{name}"
28
+ system "android update project -p #{root} -n #{name} --subprojects"
42
29
  raise "android update project failed with return code #{$?}" unless $? == 0
43
30
  end
44
31
 
@@ -51,14 +38,11 @@ module Ruboto
51
38
  FileUtils.rm_rf File.join(root, 'test', 'src', verify_package.split('.'))
52
39
  puts "Done"
53
40
  else
54
- # FIXME(uwe): Remove build.xml file to force regeneration.
55
- # FIXME(uwe): Needed when updating apps from Android SDK <= 13 to 14
56
- FileUtils.rm_f "#{root}/test/build.xml"
57
- # EMXIF
58
-
59
- puts "\nUpdating Android test project #{name} in #{root}/test..."
60
- system "android update test-project -m #{root} -p #{root}/test"
61
- raise "android update test-project failed with return code #{$?}" unless $? == 0
41
+ test_ant_properties_file = 'test/ant.properties'
42
+ test_ant_properties = File.read(test_ant_properties_file)
43
+ if test_ant_properties.gsub!(/^tested.project.dir=.*$/, 'tested.project.dir=../')
44
+ File.open(test_ant_properties_file, 'w') { |f| f << test_ant_properties }
45
+ end
62
46
  end
63
47
 
64
48
  Dir.chdir File.join(root, 'test') do
@@ -83,15 +67,12 @@ module Ruboto
83
67
  File.open("AndroidManifest.xml", 'w') { |f| test_manifest.document.write(f, 4) }
84
68
  instrumentation_property = "test.runner=org.ruboto.test.InstrumentationTestRunner\n"
85
69
 
86
- # FIXME(uwe): Cleanup when we stop supporting updating apps generated with Android SDK <= 13
87
- prop_file = %w{ant.properties build.properties}.find { |f| File.exists?(f) }
70
+ prop_file = 'ant.properties'
88
71
  prop_lines = File.readlines(prop_file)
89
72
  File.open(prop_file, 'a') { |f| f << instrumentation_property } unless prop_lines.include?(instrumentation_property)
90
- # EMXIF
91
73
 
92
- ant_setup_line = /^(\s*<\/project>)/
93
74
  run_tests_override = <<-EOF
94
- <!-- BEGIN added by ruboto -->
75
+ <!-- BEGIN added by Ruboto -->
95
76
 
96
77
  <macrodef name="run-tests-helper">
97
78
  <attribute name="emma.enabled" default="false"/>
@@ -132,12 +113,16 @@ module Ruboto
132
113
  <target name="run-tests-quick" description="Runs tests with previously installed packages">
133
114
  <run-tests-helper />
134
115
  </target>
135
- <!-- END added by ruboto -->
136
-
116
+ <!-- END added by Ruboto -->
137
117
  EOF
138
118
  ant_script = File.read('build.xml')
119
+
120
+ # FIXME(uwe): Remove when we stop support for updating from Ruboto 0.8.1 and older
139
121
  ant_script.gsub!(/\s*<!-- BEGIN added by ruboto(?:-core)? -->.*?<!-- END added by ruboto(?:-core)? -->\s*/m, '')
140
- raise "Bad ANT script" unless ant_script.gsub!(ant_setup_line, "#{run_tests_override}\n\n\\1")
122
+ # EMXIF
123
+
124
+ ant_script.gsub!(/\s*<!-- BEGIN added by Ruboto -->.*?<!-- END added by Ruboto -->\s*/m, '')
125
+ raise "Bad ANT script" unless ant_script.gsub!(/\s*(<\/project>)/, "\n\n#{run_tests_override}\n\n\\1")
141
126
  File.open('build.xml', 'w') { |f| f << ant_script }
142
127
 
143
128
  # FIXME(uwe): Remove when we stop supporting update from Ruboto < 0.5.3
@@ -189,7 +174,7 @@ module Ruboto
189
174
 
190
175
  # FIXME(uwe): Try keeping the class count low to enable installation on Android 2.3 devices
191
176
  # unless new_jruby_version =~ /^1.7.0/ && verify_target_sdk < 15
192
- log_action("Copying dexmaker.jar to libs") { copier.copy 'libs' }
177
+ log_action("Copying dx.jar to libs") { copier.copy 'libs' }
193
178
  # end
194
179
 
195
180
  reconfigure_jruby_libs(new_jruby_version)
@@ -198,21 +183,21 @@ module Ruboto
198
183
  true
199
184
  end
200
185
 
201
- def update_dexmaker(force=nil)
202
- jar_file = Dir.glob("libs/dexmaker*.jar")[0]
186
+ def update_dx_jar(force=nil)
187
+ jar_file = Dir.glob("libs/dx.jar")[0]
203
188
 
204
- # FIXME(uwe): Skip copying dexmaker to apps using RubotoCore when we include dexmaker.jar in RubotoCore
205
- # return false if !jar_file && !force
189
+ # FIXME(uwe): Skip copying dx.jar to apps using RubotoCore when we include dx.jar in RubotoCore
190
+ return if !jar_file && !force
206
191
 
207
192
  copier = AssetCopier.new Ruboto::ASSETS, File.expand_path(".")
208
- # FIXME(uwe): Skip copying dexmaker to apps using RubotoCore when we include dexmaker.jar in RubotoCore
209
- # log_action("Removing #{jar_file}") { File.delete *Dir.glob("libs/dexmaker*.jar") } if jar_file
193
+ # FIXME(uwe): Skip copying dx.jar to apps using RubotoCore when we include dx.jar in RubotoCore
194
+ log_action("Removing #{jar_file}") { File.delete jar_file } if jar_file
210
195
 
211
196
  # FIXME(uwe): Try keeping the class count low to enable installation on Android 2.3 devices
212
- # FIXME(uwe): Skip copying dexmaker to apps using RubotoCore when we include dexmaker.jar in RubotoCore
213
- # if verify_target_sdk < 15
214
- log_action("Copying dexmaker.jar to libs") { copier.copy 'libs/dexmaker*.jar' }
215
- # end
197
+ # FIXME(uwe): Skip copying dx.jar to apps using RubotoCore when we include dx.jar in RubotoCore
198
+ #if verify_target_sdk < 15
199
+ # log_action("Copying dx.jar to libs") { copier.copy 'libs' }
200
+ #end
216
201
  # EMXIF
217
202
  end
218
203
 
@@ -275,7 +260,7 @@ module Ruboto
275
260
  puts "Adding explicit super call in #{script_file}"
276
261
  script_content = File.read(script_file)
277
262
  script_content.gsub! /^(\s*)(def on_(?:create\(bundle\)|start|resume|pause|destroy)\n)/, "\\1\\2\\1 super\n"
278
- File.open(script_file, 'w'){|of| of << script_content}
263
+ File.open(script_file, 'w') { |of| of << script_content }
279
264
  end
280
265
  # EMXIF
281
266
 
@@ -285,14 +270,14 @@ module Ruboto
285
270
  generate_inheriting_file 'Class', subclass_name
286
271
  generate_subclass_or_interface(:package => package, :template => 'InheritingClass', :class => class_name,
287
272
  :name => subclass_name, :method_base => method_base, :force => force)
288
- # FIXME(uwe): Remove when we stop updating from Ruboto 0.7.0 and older
273
+ # FIXME(uwe): Remove when we stop updating from Ruboto 0.7.0 and older
289
274
  elsif source_code =~ /^\s*package\s+(\S+?)\s*;.*public\s+class\s+(\S+?)\s+extends\s+(.*?)\s\{.*^\s*private Object\[\] callbackProcs = new Object\[\d+\];/m
290
275
  package, subclass_name, class_name = $1, $2, $3
291
276
  puts "Regenerating subclass #{package}.#{subclass_name}"
292
277
  generate_inheriting_file 'Class', subclass_name
293
278
  generate_subclass_or_interface(:package => package, :template => 'InheritingClass', :class => class_name,
294
279
  :name => subclass_name, :method_base => 'on', :force => force)
295
- # EMXIF
280
+ # EMXIF
296
281
  end
297
282
  end
298
283
  end
@@ -400,7 +385,8 @@ module Ruboto
400
385
  if jruby_core_version >= '1.7.0'
401
386
  excluded_core_packages = [
402
387
  'META-INF', 'cext',
403
- 'com/headius',
388
+ # 'com/headius', included since we are trying to use DexClient
389
+ 'com/headius/invokebinder',
404
390
  'com/kenai/constantine', 'com/kenai/jffi', 'com/martiansoftware', 'ext', 'java',
405
391
  'jline', 'jni',
406
392
  'jnr/constants/platform/darwin', 'jnr/constants/platform/fake', 'jnr/constants/platform/freebsd',
@@ -468,7 +454,7 @@ module Ruboto
468
454
  # FIXME(uwe): Add a Ruboto.yml config for this if it works
469
455
  # Reduces the installation footprint, but also reduces performance and stack usage
470
456
  # FIXME(uwe): Measure the performance change
471
- if false && jruby_core_version =~ /^1.7.0/ && Dir.chdir('../..'){verify_target_sdk < 15}
457
+ if false && jruby_core_version =~ /^1.7.0/ && Dir.chdir('../..') { verify_target_sdk < 15 }
472
458
  invokers = Dir['**/*${INVOKER$*,POPULATOR}.class']
473
459
  log_action("Removing invokers & populators(#{invokers.size})") do
474
460
  FileUtils.rm invokers
@@ -481,6 +467,10 @@ module Ruboto
481
467
  # FileUtils.rm_rf dir
482
468
  #end
483
469
 
470
+ # Add our proxy class factory
471
+ `javac -source 1.6 -target 1.6 -cp .:#{Ruboto::ASSETS}/libs/dx.jar:#{Dir["#{Ruboto::SdkVersions::ANDROID_HOME}/platforms/android-*/android.jar"][0]} -d . #{Ruboto::GEM_ROOT}/lib/*.java`
472
+ raise "Compile failed" unless $? == 0
473
+
484
474
  `jar -cf ../#{jruby_core} .`
485
475
  end
486
476
  FileUtils.remove_dir "tmp", true
@@ -515,7 +505,7 @@ module Ruboto
515
505
  else
516
506
  lib_dirs = ['1.8', '1.9', 'shared']
517
507
  end
518
- # TODO end
508
+ # ODOT
519
509
 
520
510
  lib_dirs.each do |ld|
521
511
  excluded_stdlibs.each do |d|
@@ -1,4 +1,4 @@
1
1
  module Ruboto
2
- VERSION = '0.8.1'
2
+ VERSION = '0.9.0.rc.0'
3
3
  UPDATE_VERSION_LIMIT = '0.5.2'
4
4
  end
@@ -10,13 +10,14 @@ setup do |activity|
10
10
  assert @text_view
11
11
  end
12
12
 
13
- # ANDROID: 10, PLATFORM: 0.4.7, JRuby: 1.7.0.dev '28334966' expected, but got '28335067'
13
+ # ANDROID: 10, PLATFORM: 0.4.7, JRuby: 1.7.0.dev '28334966' expected, but got '28335067'
14
+ # ANDROID: 16, PLATFORM: 0.4.8.dev, JRuby: 1.7.0.preview2 '[29, 34, 47, 64]' expected, but got '[28, 33, 47, 64]'
14
15
 
15
16
  test('stack depth') do |activity|
16
17
  os_offset = {
17
18
  13 => [1]*4,
18
19
  15 => [0, 0, 1, 1],
19
- 16 => [1]*4,
20
+ 16 => [0, 0, 1, 1],
20
21
  }[android.os.Build::VERSION::SDK_INT] || [0, 0, 0, 0]
21
22
  if org.ruboto.JRubyAdapter.uses_platform_apk?
22
23
  jruby_offset = {
@@ -27,6 +28,7 @@ test('stack depth') do |activity|
27
28
  jruby_offset = {
28
29
  '1.7.0.dev' => [1, 1, 1, 1],
29
30
  '1.7.0.preview2' => [0, 0, -4, -4],
31
+ '1.7.0.rc1' => [0, 0, -4, -4],
30
32
  }[org.jruby.runtime.Constants::VERSION] || [0, 0, 0, 0]
31
33
  end
32
34
  version_message ="ANDROID: #{android.os.Build::VERSION::SDK_INT}, PLATFORM: #{org.ruboto.JRubyAdapter.uses_platform_apk ? org.ruboto.JRubyAdapter.platform_version_name : 'STANDALONE'}, JRuby: #{org.jruby.runtime.Constants::VERSION}"
@@ -0,0 +1,33 @@
1
+ require 'ruboto/activity'
2
+ require 'ruboto/widget'
3
+
4
+ ruboto_import_widgets :LinearLayout, :ListView, :TextView
5
+
6
+ class SubclassOfArrayAdapter < Java::AndroidWidget::ArrayAdapter
7
+ def get_view(position, convert_view, parent)
8
+ puts "IN get_view!!!"
9
+ @inflater ||= context.getSystemService(Context::LAYOUT_INFLATER_SERVICE)
10
+ row = convert_view ? convert_view : @inflater.inflate(mResource, nil)
11
+ row.findViewById(mFieldId).text = get_item(position)
12
+ row
13
+ rescue Exception
14
+ puts "Exception getting list item view: #$!"
15
+ puts $!.backtrace.join("\n")
16
+ convert_view
17
+ end
18
+ end
19
+
20
+ class SubclassActivity
21
+ def on_create(bundle)
22
+ super
23
+ setTitle File.basename(__FILE__).chomp('_activity.rb').split('_').map { |s| "#{s[0..0].upcase}#{s[1..-1]}" }.join(' ')
24
+
25
+ adapter = SubclassOfArrayAdapter.new(self, android.R.layout.simple_list_item_1 , AndroidIds::text1, ['Record one', 'Record two'])
26
+
27
+ self.content_view =
28
+ linear_layout :orientation => LinearLayout::VERTICAL do
29
+ @text_view_margins = text_view :text => 'What hath Matz wrought?', :id => 42
30
+ @list_view = list_view :adapter => adapter, :id => 43
31
+ end
32
+ end
33
+ end
@@ -1,4 +1,4 @@
1
- activity Java::org.ruboto.test_app.GenerateActivity
1
+ activity Java::org.ruboto.test_app.SubclassActivity
2
2
 
3
3
  setup do |activity|
4
4
  start = Time.now
@@ -39,6 +39,10 @@ module AppTestMethods
39
39
  def run_activity_tests(activity_dir)
40
40
  Dir[File.expand_path("#{activity_dir}/*_test.rb", File.dirname(__FILE__))].each do |test_src|
41
41
  snake_name = test_src.chomp('_test.rb')
42
+
43
+ # FIXME(uwe): Remove when we stop testing JRuby < 1.7.0.rc1
44
+ next if snake_name =~ /subclass/ && (RUBOTO_PLATFORM == 'CURRENT' || JRUBY_JARS_VERSION < Gem::Version.new('1.7.0.rc1'))
45
+
42
46
  activity_name = File.basename(snake_name).split('_').map { |s| "#{s[0..0].upcase}#{s[1..-1]}" }.join
43
47
  Dir.chdir APP_DIR do
44
48
  system "#{RUBOTO_CMD} gen class Activity --name #{activity_name}"
@@ -21,6 +21,7 @@ test('stack depth') do |activity|
21
21
  jruby_offset = {
22
22
  '1.7.0.preview1' => [0, -1, -1, -1],
23
23
  '1.7.0.preview2' => [0, -1, 0, 0],
24
+ '1.7.0.rc1' => [0, -1, 0, 0],
24
25
  }[org.jruby.runtime.Constants::VERSION] || [0, 0, 0, 0]
25
26
  end
26
27
  version_message ="ANDROID: #{android.os.Build::VERSION::SDK_INT}, PLATFORM: #{org.ruboto.JRubyAdapter.uses_platform_apk ? org.ruboto.JRubyAdapter.platform_version_name : 'STANDALONE'}, JRuby: #{org.jruby.runtime.Constants::VERSION}"
@@ -27,6 +27,7 @@ test('stack depth') do |activity|
27
27
  '1.7.0.dev' => [1, 0, 0, 0],
28
28
  '1.7.0.preview1' => [0, -1, -1, -1],
29
29
  '1.7.0.preview2' => [0, -1, -1, -1],
30
+ '1.7.0.rc1' => [0, -1, -1, -1],
30
31
  }[org.jruby.runtime.Constants::VERSION] || [0, 0, 0, 0]
31
32
  end
32
33
  version_message ="ANDROID: #{android.os.Build::VERSION::SDK_INT}, PLATFORM: #{org.ruboto.JRubyAdapter.uses_platform_apk ? org.ruboto.JRubyAdapter.platform_version_name : 'STANDALONE'}, JRuby: #{org.jruby.runtime.Constants::VERSION}"
@@ -13,12 +13,20 @@ if RubotoTest::RUBOTO_PLATFORM == 'STANDALONE'
13
13
  cleanup_app
14
14
  end
15
15
 
16
+ # APK was larger than 3.2MB: 3.3MB. JRuby: 1.6.7.2, ANDROID_TARGET: 10.
17
+ # APK was larger than 4.4MB: 4.7MB. JRuby: 1.7.0.preview2, ANDROID_TARGET: 10.
18
+ # APK was larger than 3.2MB: 3.5MB. JRuby: 1.6.7, ANDROID_TARGET: 15.
19
+ # APK was larger than 4.6MB: 4.9MB. JRuby: 1.7.0.preview2, ANDROID_TARGET: 15.
20
+
16
21
  def test_minimal_apk_is_less_than_3_mb
17
22
  apk_size = BigDecimal(File.size("#{APP_DIR}/bin/RubotoTestApp-debug.apk").to_s) / (1024 * 1024)
18
23
  upper_limit = {
19
- '1.6.7' => 3.2,
24
+ '1.6.7' => 3.5,
25
+ '1.6.7.2' => 3.5,
26
+ '1.6.8' => 3.5,
20
27
  '1.7.0.preview1' => 4.6,
21
- '1.7.0.preview2' => 4.6,
28
+ '1.7.0.preview2' => ANDROID_TARGET < 15 ? 4.7 : 4.9,
29
+ '1.7.0.rc1' => ANDROID_TARGET < 15 ? 4.7 : 4.9,
22
30
  }[JRUBY_JARS_VERSION.to_s] || 3.2
23
31
  lower_limit = upper_limit * 0.9
24
32
  version_message ="JRuby: #{JRUBY_JARS_VERSION}, ANDROID_TARGET: #{ANDROID_TARGET}"